From: Francis Dupont Date: Fri, 27 Feb 2015 15:47:08 +0000 (+0100) Subject: [3516] Added sectioning in both python and c++ system messages tools X-Git-Tag: trac3874_base~8^2~6 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f2b1aad25db8a3fd9fb26ac2db2b967e42a7cb9a;p=thirdparty%2Fkea.git [3516] Added sectioning in both python and c++ system messages tools --- diff --git a/tools/system_messages.cc b/tools/system_messages.cc index d9e8c48490..3eccb7de24 100644 --- a/tools/system_messages.cc +++ b/tools/system_messages.cc @@ -45,6 +45,7 @@ typedef std::vector lines_type; struct Details { std::string text; lines_type description; + std::string sname; std::string filename; }; @@ -137,7 +138,11 @@ const std::string FILE_HEADER = \n\ \n\ \n\ - Kea Log Messages\n\ + Kea Log Messages\n"; + +// This is output one for each module. $M substitution token is the name. +const std::string SECTION_HEADER = "
\n\ + $M Module\n\ \n\ \n"; @@ -153,19 +158,24 @@ $D\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 = ""; +const std::string BLANK = ""; // 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 = " \n\ \n\ - \n\ +
"; + +// The trailier is copied to the output verbatim after the last section. +const std::string FILE_TRAILER = +"
\n\ "; + /// Report an error and exit void reportError(const std::string& filename, const std::string& what) { @@ -224,7 +234,7 @@ lines_type replaceBlankLines(const lines_type lines) 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); } @@ -242,9 +252,16 @@ void printSeparator() { 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)); @@ -274,6 +291,10 @@ void printMessage(const std::string& msgid) std::cout << replaceShell(m2, 'D', m3) << "\n"; } +void printSectionTrailer() { + std::cout << SECTION_TRAILER << "\n"; +} + void printTrailer() { std::cout << FILE_TRAILER << "\n"; } @@ -330,6 +351,7 @@ lines_type removeEmptyLeadingTrailing(lines_type lines) 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. @@ -367,6 +389,8 @@ void addToDictionary(const std::string& msgid, 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(key, details)); } @@ -439,7 +463,6 @@ void processFileContent(const std::string& 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 /// and the remainder passed for message processing. @@ -518,6 +541,7 @@ void processAllFiles(const boost::filesystem::path& root) } } + void usage(char* progname) { std::cerr << "Usage: " << progname << @@ -548,6 +572,8 @@ int main(int argc, char* argv[]) } fout.open(argv[0], std::ofstream::out | std::ofstream::trunc); std::cout.rdbuf(fout.rdbuf()); + --argc; + ++argv; } } @@ -570,15 +596,28 @@ int main(int argc, char* 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); diff --git a/tools/system_messages.py b/tools/system_messages.py index f08b5a114c..a682429d91 100644 --- a/tools/system_messages.py +++ b/tools/system_messages.py @@ -57,7 +57,7 @@ dictionary = {} # illustration to make the structure clearer.) The text of these section is: # Header - this is output before anything else. -FILE_HEADER=""" +FILE_HEADER = """ @@ -119,10 +119,14 @@ FILE_HEADER=""" Kea Log Messages - - """ +# This is output one for each module. $M substitution token is the name. +SECTION_HEADER = """
+ $M Module + + """ + # 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. @@ -133,18 +137,21 @@ $D """ -# A description may contain blank lines intended to separate paragraphs. If so, -# each blank line is replaced by the following. -SEC_BLANK = "" +# A description may contain blank lines intended to separate +# paragraphs. If so, each blank line is replaced by the following. +BLANK = "" -# 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 = """ +# The trailer is copied to the output verbatim after the last message. +SECTION_TRAILER = """ - +
""" + +# The trailer is copied to the output verbatim after the last section. +FILE_TRAILER = """
""" @@ -156,7 +163,6 @@ def reportError(filename, what): 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 @@ -166,8 +172,6 @@ def replaceTag(string): string2 = string1.replace(">", ">") return string2 - - def replaceBlankLines(lines): """Replaces blank lines in an array with the contents of the 'blank' section. @@ -175,14 +179,13 @@ def replaceBlankLines(lines): 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) @@ -190,6 +193,13 @@ def printHeader(): 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. @@ -210,11 +220,13 @@ def printMessage(msgid): print(m3) +def printSectionTrailer(): + print(SECTION_TRAILER) + def printTrailer(): print(FILE_TRAILER) - def removeEmptyLeadingTrailing(lines): """Removes leading and trailing empty lines. @@ -259,7 +271,6 @@ def removeEmptyLeadingTrailing(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 @@ -269,6 +280,7 @@ def addToDictionary(msgid, msgtext, desc, filename): 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. @@ -287,13 +299,14 @@ def addToDictionary(msgid, msgtext, desc, filename): # 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, @@ -349,7 +362,6 @@ def processFileContent(filename, lines): 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 @@ -371,7 +383,6 @@ def processFile(filename): 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. @@ -410,11 +421,20 @@ if __name__ == "__main__": 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()