Kea 2.7.5
message.cc File Reference

Message Compiler. More...

#include <config.h>
#include <cctype>
#include <cstddef>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include <errno.h>
#include <getopt.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <exceptions/exceptions.h>
#include <util/filesystem.h>
#include <util/str.h>
#include <log/log_messages.h>
#include <log/message_dictionary.h>
#include <log/message_exception.h>
#include <log/message_reader.h>
#include <log/logger.h>
+ Include dependency graph for log/compiler/message.cc:

Go to the source code of this file.

Functions

void errorDuplicates (MessageReader &reader)
 Error and exit if there are duplicate entries.
 
int main (int argc, char *argv[])
 Main Program.
 
string quoteString (const string &instring)
 Quote String.
 
char replaceNonAlphaNum (char c)
 Convert Non Alpha-Numeric Characters to Underscores.
 
string sentinel (Path &file)
 Create Header Sentinel.
 
vector< string > sortedIdentifiers (MessageDictionary &dictionary)
 Sorted Identifiers.
 
vector< string > splitNamespace (string ns)
 Split Namespace.
 
void usage ()
 Print Usage.
 
void version ()
 Print Version.
 
void writeClosingNamespace (ostream &output, const vector< string > &ns)
 Write Closing Namespace(s)
 
void writeHeaderFile (const string &file, const vector< string > &ns_components, MessageDictionary &dictionary, const char *output_directory)
 Write Header File.
 
void writeOpeningNamespace (ostream &output, const vector< string > &ns)
 Write Opening Namespace(s)
 
void writeProgramFile (const string &file, const vector< string > &ns_components, MessageDictionary &dictionary, const char *output_directory)
 Write Program File.
 

Detailed Description

Message Compiler.

Overview
This is the program that takes as input a message file and produces:

  • A .h file containing message definition
  • A .cc file containing code that adds the messages to the program's message dictionary at start-up time.

Invocation
The program is invoked with the command:

kea-msg-compiler [-v | -h | -d <dir> | <message-file>]

It reads the message file and writes out two files of the same name in the current working directory (unless -d is used) but with extensions of .h and .cc.

-v causes it to print the version number and exit. -h prints a help message (and exits). -d <dir> will make it write the output file(s) to dir instead of current working directory

Definition in file log/compiler/message.cc.

Function Documentation

◆ errorDuplicates()

void errorDuplicates ( MessageReader & reader)

Error and exit if there are duplicate entries.

If the input file contained duplicate message IDs, we print an error for each of them, then exit the program with a non-0 value.

Parameters
readerMessage Reader used to read the file

Definition at line 415 of file log/compiler/message.cc.

Referenced by main().

◆ main()

int main ( int argc,
char * argv[] )

Main Program.

Parses the options then dispatches to the appropriate function. See the main file header for the invocation.

Definition at line 440 of file log/compiler/message.cc.

References errorDuplicates(), isc::log::MessageDictionary::globalDictionary(), isc::log::replacePlaceholder(), splitNamespace(), usage(), version(), writeHeaderFile(), and writeProgramFile().

+ Here is the call graph for this function:

◆ quoteString()

string quoteString ( const string & instring)

Quote String.

Inserts an escape character (a backslash) prior to any double quote characters. This is used to handle the fact that the input file does not contain quotes, yet the string will be included in a C++ literal string.

Definition at line 113 of file log/compiler/message.cc.

Referenced by writeProgramFile().

◆ replaceNonAlphaNum()

char replaceNonAlphaNum ( char c)

Convert Non Alpha-Numeric Characters to Underscores.

Simple function for use in a call to transform

Definition at line 291 of file log/compiler/message.cc.

◆ sentinel()

string sentinel ( Path & file)

Create Header Sentinel.

Given the name of a file, create an #ifdef sentinel name. The name is <name>_<ext>, where <name> is the name of the file, and <ext> is the extension less the leading period. The sentinel will be upper-case.

Parameters
filepath to the file.
Returns
Sentinel name

Definition at line 98 of file log/compiler/message.cc.

References isc::util::file::Path::extension(), isc::util::file::Path::stem(), and isc::util::str::uppercase().

Referenced by writeHeaderFile().

+ Here is the call graph for this function:

◆ sortedIdentifiers()

vector< string > sortedIdentifiers ( MessageDictionary & dictionary)

Sorted Identifiers.

Given a dictionary, return a vector holding the message IDs in sorted order.

Parameters
dictionaryDictionary to examine
Returns
Sorted list of message IDs

Definition at line 142 of file log/compiler/message.cc.

Referenced by writeHeaderFile(), and writeProgramFile().

◆ splitNamespace()

vector< string > splitNamespace ( string ns)

Split Namespace.

The $NAMESPACE directive may well specify a namespace in the form a::b. Unfortunately, the C++ "namespace" statement can only accept a single string - to set up the namespace of "a::b" requires two statements, one for "namespace a" and the other for "namespace b".

This function returns the set of namespace components as a vector of strings. A vector of one element, containing the empty string, is returned if the anonymous namespace is specified.

Parameters
nsArgument to $NAMESPACE (passed by value, as we will be modifying it.)

Definition at line 168 of file log/compiler/message.cc.

References isc::util::str::tokens().

Referenced by main().

+ Here is the call graph for this function:

◆ usage()

void usage ( )

Print Usage.

Prints program usage to stdout.

Definition at line 76 of file log/compiler/message.cc.

Referenced by isc::lfc::LFCController::launch(), isc::process::DControllerBase::launch(), main(), and isc::lfc::LFCController::parseArgs().

◆ version()

void version ( )

Print Version.

Prints the program's version number.

Definition at line 67 of file log/compiler/message.cc.

Referenced by main().

◆ writeClosingNamespace()

void writeClosingNamespace ( ostream & output,
const vector< string > & ns )

Write Closing Namespace(s)

Writes the lines listing the namespaces in use.

Definition at line 201 of file log/compiler/message.cc.

Referenced by writeHeaderFile(), and writeProgramFile().

◆ writeHeaderFile()

void writeHeaderFile ( const string & file,
const vector< string > & ns_components,
MessageDictionary & dictionary,
const char * output_directory )

Write Header File.

Writes the C++ header file containing the symbol definitions. These are "extern" references to definitions in the .cc file. As such, they should take up no space in the module in which they are included, and redundant references should be removed by the compiler.

Parameters
fileName of the message file. The header file is written to a file of the same name but with a .h suffix.
ns_componentsNamespace in which the definitions are to be placed. An empty string indicates no namespace.
dictionaryDictionary holding the message definitions.
output_directoryif not null NULL, output files are written to the given directory. If NULL, they are written to the current working directory.

Definition at line 226 of file log/compiler/message.cc.

References isc_throw_4, isc::log::LOG_OPEN_OUTPUT_FAIL, isc::log::LOG_WRITE_ERROR, sentinel(), sortedIdentifiers(), writeClosingNamespace(), and writeOpeningNamespace().

Referenced by main().

+ Here is the call graph for this function:

◆ writeOpeningNamespace()

void writeOpeningNamespace ( ostream & output,
const vector< string > & ns )

Write Opening Namespace(s)

Writes the lines listing the namespaces in use.

Definition at line 186 of file log/compiler/message.cc.

Referenced by writeHeaderFile(), and writeProgramFile().

◆ writeProgramFile()

void writeProgramFile ( const string & file,
const vector< string > & ns_components,
MessageDictionary & dictionary,
const char * output_directory )

Write Program File.

Writes the C++ source code file. This defines the text of the message symbols, as well as the initializer object that sets the entries in the global dictionary.

The construction of the initializer object loads the dictionary with the message text. However, nothing actually references it. If the initializer were in a file by itself, the lack of things referencing it would cause the linker to ignore it when pulling modules out of the logging library in a static link. By including it in the file with the symbol definitions, the module will get included in the link process to resolve the symbol definitions, and so the initializer object will be included in the final image. (Note that there are no such problems when the logging library is built as a dynamically-linked library: the whole library - including the initializer module - gets mapped into address space when the library is loaded, after which all the initializing code (including the constructors of objects declared outside functions) gets run.)

There may be a problem when we come to port this to Windows. Microsoft Visual Studio contains a "Whole Program Optimization" option, where the optimization is done at link-time, not compiler-time. In this it may decide to remove the initializer object because of a lack of references to it. But until BIND-10 is ported to Windows, we won't know.

Parameters
fileName of the message file. The header file is written to a file of the same name but with a .h suffix.
ns_componentsNamespace in which the definitions are to be placed. An empty string indicates no namespace.
dictionaryDictionary holding the message definitions.
output_directoryif not null NULL, output files are written to the given directory. If NULL, they are written to the current working directory.

Definition at line 329 of file log/compiler/message.cc.

References isc_throw_4, isc::log::LOG_OPEN_OUTPUT_FAIL, isc::log::LOG_WRITE_ERROR, quoteString(), sortedIdentifiers(), writeClosingNamespace(), and writeOpeningNamespace().

Referenced by main().

+ Here is the call graph for this function: