Logging Messages Message Storage =============== Each message is identified by a string identifier, e.g. "INVFILNAM", which is associated with some text (e.g. "%s is an invalid file name"). These are stored in a single std::map, in a class called the Dictionary. The message identifier (along with parameters) is passed through the logging system to an appender, which uses the identifier to look up the message in the dictionary. The message is then formatted and written out. Message File ============ A message file is a file containing message definitions. Typically there will be one message file for each component that declares message symbols. A example file could be: # Example message file # $ID:$ $PREFIX TEST_ TEST1 message %s is much too large + This message is a test for the general message code UNKNOWN unknown message + Issued when the message is unknown. Point to note: * Leading and trailing space are trimmed from the line. * Blank lines are ignored * Lines starting with "#" are comments are are ignored. * Lines starting $ are directives. At present, the only directive recognised is $PREFIX, which has one argument: the string used to prefix symbols. If there is no facility directive, there is no prefix to the symbols. * Lines starting + indicate an explanation for the preceding message. These are processed by a separate program and used to generate an error messages manual. However they are treated like comments here. * Message lines. These comprise a symbol name and a message (which includes C-style substitution strings). Message Compiler ================ The message compiler produces two files: 1) A C++ header file (called .h) that holds lines of the form: namespace { const char* PREFIX_IDENTIFIER = "identifier"; : } These are just convenience symbols to avoid the need to type in the string in quotes. PREFIX_ is the string in the $PREFIX directive and is used to avoid potential clashes with system-defined symbols. 2) A C++ source file (called .cpp) that holds the code to insert the symbols and messages into the map. This file declares an array of identifiers/messages in the form: namespace { const char* messages = { identifier1, text1, identifier2, text2, : NULL }; } (A more complex structure to group identifiers and their messages could be imposed, but as the array is generated by code and will be read by code, it is not needed.) It then declares an object that will add information to the global dictionary: DictionaryAppender __