struct Details {
std::string text;
lines_type description;
+ std::string sname;
std::string filename;
};
</chapter>\n\
\n\
<chapter id=\"messages\">\n\
- <title>Kea Log Messages</title>\n\
+ <title>Kea Log Messages</title>\n";
+
+// This is output one for each module. $M substitution token is the name.
+const std::string SECTION_HEADER = " <section id=\"$M\">\n\
+ <title>$M Module</title>\n\
<para>\n\
<variablelist>\n";
// A description may contain blank lines intended to separate
// paragraphs. If so, each blank line is replaced by the following.
-const std::string SEC_BLANK = "</para><para>";
+const std::string BLANK = "</para><para>";
// The separator is copied to the output verbatim after each message except
// the last.
const std::string SEPARATOR = "";
// The trailier is copied to the output verbatim after the last message.
-const std::string FILE_TRAILER =
+const std::string SECTION_TRAILER =
" </variablelist>\n\
</para>\n\
- </chapter>\n\
+ </section>";
+
+// The trailier is copied to the output verbatim after the last section.
+const std::string FILE_TRAILER =
+" </chapter>\n\
</book>";
+
/// Report an error and exit
void reportError(const std::string& filename, const std::string& what)
{
lines_type result;
for (lines_type::const_iterator l = lines.begin(); l != lines.end(); ++l) {
if (l->empty()) {
- result.push_back(SEC_BLANK);
+ result.push_back(BLANK);
} else {
result.push_back(*l);
}
std::cout << SEPARATOR << "\n";
}
+void printSectionHeader(const std::string& sname)
+{
+ // In the section name, replace "<" and ">" with XML-safe versions and
+ // substitute into the data.
+ std::cout << replaceShell(SECTION_HEADER, 'M', replaceTag(sname));
+}
+
void printMessage(const std::string& msgid)
{
- //In the message ID, replace "<" and ">" with XML-safe versions and
+ // In the message ID, replace "<" and ">" with XML-safe versions and
// substitute into the data.
const std::string m0 = ID_MESSAGE;
const std::string m1 = replaceShell(m0, 'I', replaceTag(msgid));
std::cout << replaceShell(m2, 'D', m3) << "\n";
}
+void printSectionTrailer() {
+ std::cout << SECTION_TRAILER << "\n";
+}
+
void printTrailer() {
std::cout << FILE_TRAILER << "\n";
}
return retlines;
}
+
/// Add the current message ID and associated information to the global
/// dictionary. If a message with that ID already exists, loop appending
/// suffixes of the form "(n)" to it until one is found that doesn't.
Details details;
details.text = msgtext;
details.description = removeEmptyLeadingTrailing(desc);
+ size_t underscore = msgid.find_first_of('_');
+ details.sname = msgid.substr(0, underscore);
details.filename = filename;
dictionary.insert(std::pair<const std::string, Details>(key, details));
}
}
}
-
/// Processes a file by reading it in and stripping out all comments and
/// and directives. Leading and trailing blank lines in the file are removed
/// and the remainder passed for message processing.
}
}
+
void usage(char* progname)
{
std::cerr << "Usage: " << progname <<
}
fout.open(argv[0], std::ofstream::out | std::ofstream::trunc);
std::cout.rdbuf(fout.rdbuf());
+ --argc;
+ ++argv;
}
}
// Now just print out everything we've read (in alphabetical order).
bool first = true;
+ std::string sname;
printHeader();
for (dictionary_type::iterator it = dictionary.begin();
it != dictionary.end();
++it) {
- if (!first) {
- printSeparator();
- }
- first = false;
- printMessage(it->first);
+ if (sname.compare(it->second.sname) != 0) {
+ if (!sname.empty()) {
+ printSectionTrailer();
+ printSeparator();
+ }
+ sname = it->second.sname;
+ printSectionHeader(sname);
+ first = true;
+ }
+ if (!first) {
+ printSeparator();
+ }
+ first = false;
+ printMessage(it->first);
+ }
+ if (!sname.empty()) {
+ printSectionTrailer();
}
printTrailer();
exit(0);
# illustration to make the structure clearer.) The text of these section is:
# Header - this is output before anything else.
-FILE_HEADER="""<?xml version="1.0" encoding="UTF-8"?>
+FILE_HEADER = """<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
<!ENTITY mdash "—" >
<chapter id="messages">
<title>Kea Log Messages</title>
- <para>
- <variablelist>
"""
+# This is output one for each module. $M substitution token is the name.
+SECTION_HEADER = """ <section id="$M">
+ <title>$M Module</title>
+ <para>
+ <variablelist>"""
+
# This is output once for each message. The string contains substitution
# tokens: $I is replaced by the message identification, $T by the message text,
# and $D by the message description.
</para></listitem>
</varlistentry>"""
-# A description may contain blank lines intended to separate paragraphs. If so,
-# each blank line is replaced by the following.
-SEC_BLANK = "</para><para>"
+# A description may contain blank lines intended to separate
+# paragraphs. If so, each blank line is replaced by the following.
+BLANK = "</para><para>"
-# The separator is copied to the output verbatim after each message except
-# the last.
+# The separator is copied to the output verbatim after each message or
+# section except the last.
SEPARATOR = ""
-# The trailier is copied to the output verbatim after the last message.
-FILE_TRAILER = """ </variablelist>
+# The trailer is copied to the output verbatim after the last message.
+SECTION_TRAILER = """ </variablelist>
</para>
- </chapter>
+ </section>"""
+
+# The trailer is copied to the output verbatim after the last section.
+FILE_TRAILER = """ </chapter>
</book>"""
sys.exit(1)
-
def replaceTag(string):
"""Replaces the '<' and '>' in text about to be inserted into the template
sections above with < and > to avoid problems with message text
string2 = string1.replace(">", ">")
return string2
-
-
def replaceBlankLines(lines):
"""Replaces blank lines in an array with the contents of the 'blank'
section.
result = []
for l in lines:
if len(l) == 0:
- result.append(SEC_BLANK)
+ result.append(BLANK)
else:
result.append(l)
return result
-
# Printing functions
def printHeader():
print(FILE_HEADER)
def printSeparator():
print(SEPARATOR)
+def printSectionHeader(sname):
+ # In the section name, replace "<" and ">" with XML-safe versions and
+ # substitute into the data.
+ m = SECTION_HEADER.replace("$M", replaceTag(sname));
+
+ print(m)
+
def printMessage(msgid):
# In the message ID, replace "<" and ">" with XML-safe versions and
# substitute into the data.
print(m3)
+def printSectionTrailer():
+ print(SECTION_TRAILER)
+
def printTrailer():
print(FILE_TRAILER)
-
def removeEmptyLeadingTrailing(lines):
"""Removes leading and trailing empty lines.
return retlines
-
def addToDictionary(msgid, msgtext, desc, filename):
"""Add the current message ID and associated information to the global
dictionary. If a message with that ID already exists, loop appending
msgid Message ID
msgtext Message text
desc Message description
+ sname Section name (part before the first _ of the ID)
filename File from which the message came. Currently this is
not used, but a future enhancement may wish to include the
name of the message file in the messages manual.
# add everything into a subdictionary which is then added to the main
# one.
details = {}
+ words = re.split("_", msgid)
details['text'] = msgtext
details['description'] = removeEmptyLeadingTrailing(desc)
+ details['sname'] = words[0]
details['filename'] = filename
dictionary[msgid] = details
-
def processFileContent(filename, lines):
"""Processes file content. Messages and descriptions are identified and
added to a dictionary (keyed by message ID). If the key already exists,
addToDictionary(msgid, msgtext, description, filename)
-
def processFile(filename):
"""Processes a file by reading it in and stripping out all comments and
and directives. Leading and trailing blank lines in the file are removed
processFileContent(filename, lines)
-
def processAllFiles(root):
"""Iterates through all files in the tree starting at the given root and
calls processFile for all .mes files found.
processAllFiles(args[0])
# Now just print out everything we've read (in alphabetical order).
- count = 1
+ sname = ""
printHeader()
for msgid in sorted(dictionary):
+ if dictionary[msgid]['sname'] != sname:
+ if sname != "":
+ printSectionTrailer()
+ printSeparator()
+ sname = dictionary[msgid]['sname']
+ printSectionHeader(sname)
+ count = 1
if count > 1:
printSeparator()
count = count + 1
printMessage(msgid)
+ if sname !="":
+ printSectionTrailer()
printTrailer()