Commit 182328df authored by Michal 'vorner' Vaner's avatar Michal 'vorner' Vaner
Browse files

Merge branch 'work/pyfiles'

parents 21b0e9d2 5f20e1ed
......@@ -35,6 +35,8 @@
#include <log/logger.h>
#include <boost/foreach.hpp>
using namespace std;
using namespace isc::log;
using namespace isc::util;
......@@ -78,10 +80,11 @@ version() {
void
usage() {
cout <<
"Usage: message [-h] [-v] <message-file>\n" <<
"Usage: message [-h] [-v] [-p] <message-file>\n" <<
"\n" <<
"-h Print this message and exit\n" <<
"-v Print the program version and exit\n" <<
"-p Output python source instead of C++ ones\n" <<
"\n" <<
"<message-file> is the name of the input message file.\n";
}
......@@ -237,6 +240,44 @@ writeClosingNamespace(ostream& output, const vector<string>& ns) {
}
}
/// \breif Write python file
///
/// Writes the python file containing the symbol definitions as module level
/// constants. These are objects which register themself at creation time,
/// so they can be replaced by dictionary later.
///
/// \param file Name of the message file. The source code is written to a file
/// file of the same name but with a .py suffix.
/// \param dictionary The dictionary holding the message definitions.
///
/// \note We don't use the namespace as in C++. We don't need it, because
/// python file/module works as implicit namespace as well.
void
writePythonFile(const string& file, MessageDictionary& dictionary) {
Filename message_file(file);
Filename python_file(Filename(message_file.name()).useAsDefault(".py"));
// Open the file for writing
ofstream pyfile(python_file.fullName().c_str());
// Write the comment and imports
pyfile <<
"# File created from " << message_file.fullName() << " on " <<
currentTime() << "\n" <<
"\n" <<
"import isc.log.message\n" <<
"\n";
vector<string> idents(sortedIdentifiers(dictionary));
BOOST_FOREACH(const string& ident, idents) {
pyfile << ident << " = isc.log.message.create(\"" <<
ident << "\", \"" << quoteString(dictionary.getText(ident)) <<
"\")\n";
}
pyfile.close();
}
/// \brief Write Header File
///
......@@ -264,52 +305,46 @@ writeHeaderFile(const string& file, const vector<string>& ns_components,
// Open the output file for writing
ofstream hfile(header_file.fullName().c_str());
try {
if (hfile.fail()) {
throw MessageException(MSG_OPENOUT, header_file.fullName(),
strerror(errno));
}
// Write the header preamble. If there is an error, we'll pick it up
// after the last write.
hfile <<
"// File created from " << message_file.fullName() << " on " <<
currentTime() << "\n" <<
"\n" <<
"#ifndef " << sentinel_text << "\n" <<
"#define " << sentinel_text << "\n" <<
"\n" <<
"#include <log/message_types.h>\n" <<
"\n";
// Write the message identifiers, bounded by a namespace declaration
writeOpeningNamespace(hfile, ns_components);
vector<string> idents = sortedIdentifiers(dictionary);
for (vector<string>::const_iterator j = idents.begin();
j != idents.end(); ++j) {
hfile << "extern const isc::log::MessageID " << *j << ";\n";
}
hfile << "\n";
if (hfile.fail()) {
throw MessageException(MSG_OPENOUT, header_file.fullName(),
strerror(errno));
}
writeClosingNamespace(hfile, ns_components);
// Write the header preamble. If there is an error, we'll pick it up
// after the last write.
hfile <<
"// File created from " << message_file.fullName() << " on " <<
currentTime() << "\n" <<
"\n" <<
"#ifndef " << sentinel_text << "\n" <<
"#define " << sentinel_text << "\n" <<
"\n" <<
"#include <log/message_types.h>\n" <<
"\n";
// Write the message identifiers, bounded by a namespace declaration
writeOpeningNamespace(hfile, ns_components);
vector<string> idents = sortedIdentifiers(dictionary);
for (vector<string>::const_iterator j = idents.begin();
j != idents.end(); ++j) {
hfile << "extern const isc::log::MessageID " << *j << ";\n";
}
hfile << "\n";
// ... and finally the postamble
hfile << "#endif // " << sentinel_text << "\n";
writeClosingNamespace(hfile, ns_components);
// Report errors (if any) and exit
if (hfile.fail()) {
throw MessageException(MSG_WRITERR, header_file.fullName(),
strerror(errno));
}
// ... and finally the postamble
hfile << "#endif // " << sentinel_text << "\n";
hfile.close();
}
catch (MessageException&) {
hfile.close();
throw;
// Report errors (if any) and exit
if (hfile.fail()) {
throw MessageException(MSG_WRITERR, header_file.fullName(),
strerror(errno));
}
hfile.close();
}
......@@ -357,76 +392,71 @@ writeProgramFile(const string& file, const vector<string>& ns_components,
// Open the output file for writing
ofstream ccfile(program_file.fullName().c_str());
try {
if (ccfile.fail()) {
throw MessageException(MSG_OPENOUT, program_file.fullName(),
strerror(errno));
}
// Write the preamble. If there is an error, we'll pick it up after
// the last write.
if (ccfile.fail()) {
throw MessageException(MSG_OPENOUT, program_file.fullName(),
strerror(errno));
}
ccfile <<
"// File created from " << message_file.fullName() << " on " <<
currentTime() << "\n" <<
"\n" <<
"#include <cstddef>\n" <<
"#include <log/message_types.h>\n" <<
"#include <log/message_initializer.h>\n" <<
"\n";
// Write the preamble. If there is an error, we'll pick it up after
// the last write.
// Declare the message symbols themselves.
ccfile <<
"// File created from " << message_file.fullName() << " on " <<
currentTime() << "\n" <<
"\n" <<
"#include <cstddef>\n" <<
"#include <log/message_types.h>\n" <<
"#include <log/message_initializer.h>\n" <<
"\n";
writeOpeningNamespace(ccfile, ns_components);
// Declare the message symbols themselves.
vector<string> idents = sortedIdentifiers(dictionary);
for (vector<string>::const_iterator j = idents.begin();
j != idents.end(); ++j) {
ccfile << "extern const isc::log::MessageID " << *j <<
" = \"" << *j << "\";\n";
}
ccfile << "\n";
writeOpeningNamespace(ccfile, ns_components);
writeClosingNamespace(ccfile, ns_components);
vector<string> idents = sortedIdentifiers(dictionary);
for (vector<string>::const_iterator j = idents.begin();
j != idents.end(); ++j) {
ccfile << "extern const isc::log::MessageID " << *j <<
" = \"" << *j << "\";\n";
}
ccfile << "\n";
// Now the code for the message initialization.
writeClosingNamespace(ccfile, ns_components);
ccfile <<
"namespace {\n" <<
"\n" <<
"const char* values[] = {\n";
// Now the code for the message initialization.
// Output the identifiers and the associated text.
idents = sortedIdentifiers(dictionary);
for (vector<string>::const_iterator i = idents.begin();
i != idents.end(); ++i) {
ccfile << " \"" << *i << "\", \"" <<
quoteString(dictionary.getText(*i)) << "\",\n";
}
ccfile <<
"namespace {\n" <<
"\n" <<
"const char* values[] = {\n";
// Output the identifiers and the associated text.
idents = sortedIdentifiers(dictionary);
for (vector<string>::const_iterator i = idents.begin();
i != idents.end(); ++i) {
ccfile << " \"" << *i << "\", \"" <<
quoteString(dictionary.getText(*i)) << "\",\n";
}
// ... and the postamble
ccfile <<
" NULL\n" <<
"};\n" <<
"\n" <<
"const isc::log::MessageInitializer initializer(values);\n" <<
"\n" <<
"} // Anonymous namespace\n" <<
"\n";
// Report errors (if any) and exit
if (ccfile.fail()) {
throw MessageException(MSG_WRITERR, program_file.fullName(),
strerror(errno));
}
ccfile.close();
}
catch (MessageException&) {
ccfile.close();
throw;
// ... and the postamble
ccfile <<
" NULL\n" <<
"};\n" <<
"\n" <<
"const isc::log::MessageInitializer initializer(values);\n" <<
"\n" <<
"} // Anonymous namespace\n" <<
"\n";
// Report errors (if any) and exit
if (ccfile.fail()) {
throw MessageException(MSG_WRITERR, program_file.fullName(),
strerror(errno));
}
ccfile.close();
}
......@@ -466,13 +496,19 @@ warnDuplicates(MessageReader& reader) {
int
main(int argc, char* argv[]) {
const char* soptions = "hv"; // Short options
const char* soptions = "hvp"; // Short options
optind = 1; // Ensure we start a new scan
int opt; // Value of the option
bool doPython = false;
while ((opt = getopt(argc, argv, soptions)) != -1) {
switch (opt) {
case 'p':
doPython = true;
break;
case 'h':
usage();
return 0;
......@@ -508,15 +544,27 @@ main(int argc, char* argv[]) {
MessageReader reader(&dictionary);
reader.readFile(message_file);
// Get the namespace into which the message definitions will be put and
// split it into components.
vector<string> ns_components = splitNamespace(reader.getNamespace());
// Write the header file.
writeHeaderFile(message_file, ns_components, dictionary);
// Write the file that defines the message symbols and text
writeProgramFile(message_file, ns_components, dictionary);
if (doPython) {
// Warn in case of ignored directives
if (!reader.getNamespace().empty()) {
cerr << "Python mode, ignoring the $NAMESPACE directive" <<
endl;
}
// Write the whole python file
writePythonFile(message_file, dictionary);
} else {
// Get the namespace into which the message definitions will be put and
// split it into components.
vector<string> ns_components =
splitNamespace(reader.getNamespace());
// Write the header file.
writeHeaderFile(message_file, ns_components, dictionary);
// Write the file that defines the message symbols and text
writeProgramFile(message_file, ns_components, dictionary);
}
// Finally, warn of any duplicates encountered.
warnDuplicates(reader);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment