xml: generating better xml output

This commit is contained in:
Daniel Marjamäki 2009-02-01 18:00:47 +00:00
parent eb9563faed
commit 385c28a02e
12 changed files with 122 additions and 67 deletions

View File

@ -97,8 +97,8 @@ std::string CppCheck::parseFromArgs(int argc, const char* const argv[])
_settings._force = true;
// Write results in results.xml
else if (strcmp(argv[i], "--xml-results") == 0)
_settings._xmlResults = true;
else if (strcmp(argv[i], "--xml") == 0)
_settings._xml = true;
// Check if there are unused functions
else if (strcmp(argv[i], "--unused-functions") == 0)
@ -169,7 +169,7 @@ std::string CppCheck::parseFromArgs(int argc, const char* const argv[])
"\n"
"Syntax:\n"
" cppcheck [--all] [--force] [--help] [-Idir] [--quiet] [--style]\n"
" [--unused-functions] [--verbose] [--xml-results]\n"
" [--unused-functions] [--verbose] [--xml]\n"
" [file or path1] [file or path]\n"
"\n"
"If path is given instead of filename, *.cpp, *.cxx, *.cc, *.c++ and *.c files\n"
@ -187,7 +187,7 @@ std::string CppCheck::parseFromArgs(int argc, const char* const argv[])
" -s, --style Check coding style\n"
" --unused-functions Check if there are unused functions\n"
" -v, --verbose More detailed error reports\n"
" --xml-results Write results in results.xml\n"
" --xml Write results in results.xml\n"
"\n"
"Example usage:\n"
" # Recursively check the current folder. Print the progress on the screen and\n"
@ -285,22 +285,14 @@ unsigned int CppCheck::check()
_checkFunctionUsage.check();
}
// xml results..
if (_settings._xmlResults)
if (_settings._xml)
{
std::ofstream fxml("results.xml");
fxml << "<cppcheckResults>\n"
<< " <test result=\"" << (_errorList.empty() ? "OK" : "ERROR") << "\"/>\n"
<< " <name>cppcheck</name>\n";
if (_errorList.size())
{
fxml << " <message>\n";
for (std::list<std::string>::const_iterator it = _errorList.begin(); it != _errorList.end(); ++it)
fxml << *it << "\n";
fxml << " </message>\n";
}
fxml << " </test>\n"
<< "</cppcheckResults>\n";
std::ofstream fxml("result.xml");
fxml << "<?xml version=\"1.0\"?>\n";
fxml << "<results>\n";
for (std::list<std::string>::const_iterator it = _xmllist.begin(); it != _xmllist.end(); ++it)
fxml << " " << *it << "\n";
fxml << "</results>";
}
unsigned int result = _errorList.size();
@ -464,3 +456,17 @@ void CppCheck::reportOut(const std::string & /*outmsg*/)
// This is currently never called. It is here just to comply with
// the interface.
}
void CppCheck::reportXml(const std::string &file, const std::string &line, const std::string &id, const std::string &severity, const std::string &msg)
{
std::ostringstream xml;
xml << "<error";
xml << " file=\"" + file + "\"";
xml << " line=\"" + line + "\"";
xml << " id=\"" + id + "\"";
xml << " severity=\"" + severity + "\"";
xml << " msg=\"" + msg + "\"";
xml << "/>";
_xmllist.push_back(xml.str());
}

View File

@ -113,6 +113,9 @@ private:
*/
virtual void reportOut(const std::string &outmsg);
/** xml output of errors */
virtual void reportXml(const std::string &file, const std::string &line, const std::string &id, const std::string &severity, const std::string &msg);
std::list<std::string> _errorList;
std::ostringstream _errout;
Settings _settings;
@ -128,6 +131,8 @@ private:
/** List of include paths, e.g. "my/includes/" which should be used
for finding include files inside source files. */
std::list<std::string> _includePaths;
std::list<std::string> _xmllist;
};
#endif // CPPCHECK_H

View File

@ -19,6 +19,7 @@
#include "cppcheckexecutor.h"
#include "cppcheck.h"
#include <fstream>
#include <iostream>
CppCheckExecutor::CppCheckExecutor()
@ -55,3 +56,8 @@ void CppCheckExecutor::reportOut(const std::string &outmsg)
{
std::cout << outmsg << std::endl;
}
void CppCheckExecutor::reportXml(const std::string & /*file*/, const std::string & /*line*/, const std::string & /*id*/, const std::string & /*severity*/, const std::string & /*msg*/)
{
// never used
}

View File

@ -71,6 +71,9 @@ public:
* @param outmsg, E.g. "Checking main.cpp..."
*/
virtual void reportOut(const std::string &outmsg);
/** xml output of errors */
virtual void reportXml(const std::string &file, const std::string &line, const std::string &id, const std::string &severity, const std::string &msg);
};
#endif // CPPCHECKEXECUTOR_H

View File

@ -46,6 +46,18 @@ public:
* @param outmsg, E.g. "Checking main.cpp..."
*/
virtual void reportOut(const std::string &outmsg) = 0;
/**
* XML output of error / warning
* Todo: callstack handling
*
* @param file filepath (can be "")
* @param line line (can be "")
* @param id error id (function name)
* @param severity severity of error (always, all, style, all+style, never)
* @param msg error message in plain text
*/
virtual void reportXml(const std::string &file, const std::string &line, const std::string &id, const std::string &severity, const std::string &msg) = 0;
};
#endif // #ifndef ERRORLOGGER_H

View File

@ -24,13 +24,25 @@
#include <sstream>
void ErrorMessage::_writemsg(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *tok, const char severity[], const std::string msg)
void ErrorMessage::_writemsg(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *tok, const char severity[], const std::string msg, const std::string &id)
{
logger->reportErr(tokenizer->fileLine(tok) + ": (" + severity + ") " + msg);
std::list<const Token *> callstack;
callstack.push_back(tok);
_writemsg(logger, tokenizer, callstack, severity, msg, id);
}
void ErrorMessage::_writemsg(ErrorLogger *logger, const Tokenizer *tokenizer, const std::list<const Token *> &callstack, const char severity[], const std::string msg)
void ErrorMessage::_writemsg(ErrorLogger *logger, const Tokenizer *tokenizer, const std::list<const Token *> &callstack, const char severity[], const std::string msg, const std::string &id)
{
// Todo.. callstack handling
const std::string &file(tokenizer->getFiles()->at(callstack.back()->fileIndex()));
std::ostringstream linenr;
linenr << callstack.back()->linenr();
logger->reportXml(file,
linenr.str(),
id,
severity,
msg);
std::ostringstream ostr;
for (std::list<const Token *>::const_iterator tok = callstack.begin(); tok != callstack.end(); ++tok)
ostr << (tok == callstack.begin() ? "" : " -> ") << tokenizer->fileLine(*tok);
@ -38,7 +50,13 @@ void ErrorMessage::_writemsg(ErrorLogger *logger, const Tokenizer *tokenizer, co
}
void ErrorMessage::_writemsg(ErrorLogger *logger, const std::string msg)
void ErrorMessage::_writemsg(ErrorLogger *logger, const std::string msg, const std::string &id)
{
std::ostringstream xml;
xml << "<error";
xml << " id=\"" << id << "\"";
xml << " msg=\"" << msg << "\"";
xml << ">";
logger->reportErr(msg);
}

View File

@ -31,13 +31,13 @@ class ErrorMessage
{
private:
ErrorMessage() { }
static void _writemsg(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *tok, const char severity[], const std::string msg);
static void _writemsg(ErrorLogger *logger, const Tokenizer *tokenizer, const std::list<const Token *> &callstack, const char severity[], const std::string msg);
static void _writemsg(ErrorLogger *logger, const std::string msg);
static void _writemsg(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *tok, const char severity[], const std::string msg, const std::string &id);
static void _writemsg(ErrorLogger *logger, const Tokenizer *tokenizer, const std::list<const Token *> &callstack, const char severity[], const std::string msg, const std::string &id);
static void _writemsg(ErrorLogger *logger, const std::string msg, const std::string &id);
public:
static void arrayIndexOutOfBounds(ErrorLogger *logger, const Tokenizer *tokenizer, const std::list<const Token *> &Location)
{
_writemsg(logger, tokenizer, Location, "all", "Array index out of bounds");
_writemsg(logger, tokenizer, Location, "all", "Array index out of bounds", "arrayIndexOutOfBounds");
}
static bool arrayIndexOutOfBounds(const Settings &s)
{
@ -46,7 +46,7 @@ public:
static void bufferOverrun(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location)
{
_writemsg(logger, tokenizer, Location, "all", "Buffer overrun");
_writemsg(logger, tokenizer, Location, "all", "Buffer overrun", "bufferOverrun");
}
static bool bufferOverrun(const Settings &s)
{
@ -55,7 +55,7 @@ public:
static void outOfBounds(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location, const std::string &what)
{
_writemsg(logger, tokenizer, Location, "always", "" + what + " is out of bounds");
_writemsg(logger, tokenizer, Location, "always", "" + what + " is out of bounds", "outOfBounds");
}
static bool outOfBounds()
{
@ -64,7 +64,7 @@ public:
static void noConstructor(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location, const std::string &classname)
{
_writemsg(logger, tokenizer, Location, "style", "The class '" + classname + "' has no constructor");
_writemsg(logger, tokenizer, Location, "style", "The class '" + classname + "' has no constructor", "noConstructor");
}
static bool noConstructor(const Settings &s)
{
@ -73,7 +73,7 @@ public:
static void uninitVar(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location, const std::string &classname, const std::string &varname)
{
_writemsg(logger, tokenizer, Location, "always", "Uninitialized member variable '" + classname + "::" + varname + "'");
_writemsg(logger, tokenizer, Location, "always", "Uninitialized member variable '" + classname + "::" + varname + "'", "uninitVar");
}
static bool uninitVar()
{
@ -82,7 +82,7 @@ public:
static void unusedPrivateFunction(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location, const std::string &classname, const std::string &funcname)
{
_writemsg(logger, tokenizer, Location, "style", "Unused private function '" + classname + "::" + funcname + "'");
_writemsg(logger, tokenizer, Location, "style", "Unused private function '" + classname + "::" + funcname + "'", "unusedPrivateFunction");
}
static bool unusedPrivateFunction(const Settings &s)
{
@ -91,7 +91,7 @@ public:
static void memsetClass(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location, const std::string &memfunc)
{
_writemsg(logger, tokenizer, Location, "always", "Using '" + memfunc + "' on class");
_writemsg(logger, tokenizer, Location, "always", "Using '" + memfunc + "' on class", "memsetClass");
}
static bool memsetClass()
{
@ -100,7 +100,7 @@ public:
static void memsetStruct(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location, const std::string &memfunc, const std::string &classname)
{
_writemsg(logger, tokenizer, Location, "always", "Using '" + memfunc + "' on struct that contains a 'std::" + classname + "'");
_writemsg(logger, tokenizer, Location, "always", "Using '" + memfunc + "' on struct that contains a 'std::" + classname + "'", "memsetStruct");
}
static bool memsetStruct()
{
@ -109,7 +109,7 @@ public:
static void operatorEq(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location)
{
_writemsg(logger, tokenizer, Location, "style", "'operator=' should return something");
_writemsg(logger, tokenizer, Location, "style", "'operator=' should return something", "operatorEq");
}
static bool operatorEq(const Settings &s)
{
@ -118,7 +118,7 @@ public:
static void virtualDestructor(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location, const std::string &Base, const std::string &Derived)
{
_writemsg(logger, tokenizer, Location, "always", "Class " + Base + " which is inherited by class " + Derived + " does not have a virtual destructor");
_writemsg(logger, tokenizer, Location, "always", "Class " + Base + " which is inherited by class " + Derived + " does not have a virtual destructor", "virtualDestructor");
}
static bool virtualDestructor()
{
@ -127,7 +127,7 @@ public:
static void unusedFunction(ErrorLogger *logger, const std::string &filename, const std::string &funcname)
{
_writemsg(logger, "[" + filename + "]: The function '" + funcname + "' is never used");
_writemsg(logger, "[" + filename + "]: The function '" + funcname + "' is never used", "unusedFunction");
}
static bool unusedFunction(const Settings &s)
{
@ -136,7 +136,7 @@ public:
static void mismatchAllocDealloc(ErrorLogger *logger, const Tokenizer *tokenizer, const std::list<const Token *> &Location, const std::string &varname)
{
_writemsg(logger, tokenizer, Location, "all", "Mismatching allocation and deallocation: " + varname + "");
_writemsg(logger, tokenizer, Location, "all", "Mismatching allocation and deallocation: " + varname + "", "mismatchAllocDealloc");
}
static bool mismatchAllocDealloc(const Settings &s)
{
@ -145,7 +145,7 @@ public:
static void memleak(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location, const std::string &varname)
{
_writemsg(logger, tokenizer, Location, "always", "Memory leak: " + varname + "");
_writemsg(logger, tokenizer, Location, "always", "Memory leak: " + varname + "", "memleak");
}
static bool memleak()
{
@ -154,7 +154,7 @@ public:
static void memleakall(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location, const std::string &varname)
{
_writemsg(logger, tokenizer, Location, "all", "Memory leak: " + varname + "");
_writemsg(logger, tokenizer, Location, "all", "Memory leak: " + varname + "", "memleakall");
}
static bool memleakall(const Settings &s)
{
@ -163,7 +163,7 @@ public:
static void resourceLeak(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location, const std::string &varname)
{
_writemsg(logger, tokenizer, Location, "always", "Resource leak: " + varname + "");
_writemsg(logger, tokenizer, Location, "always", "Resource leak: " + varname + "", "resourceLeak");
}
static bool resourceLeak()
{
@ -172,7 +172,7 @@ public:
static void deallocDealloc(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location, const std::string &varname)
{
_writemsg(logger, tokenizer, Location, "always", "Deallocating a deallocated pointer: " + varname + "");
_writemsg(logger, tokenizer, Location, "always", "Deallocating a deallocated pointer: " + varname + "", "deallocDealloc");
}
static bool deallocDealloc()
{
@ -181,7 +181,7 @@ public:
static void deallocuse(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location, const std::string &varname)
{
_writemsg(logger, tokenizer, Location, "always", "Using '" + varname + "' after it is deallocated / released");
_writemsg(logger, tokenizer, Location, "always", "Using '" + varname + "' after it is deallocated / released", "deallocuse");
}
static bool deallocuse()
{
@ -190,7 +190,7 @@ public:
static void cstyleCast(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location)
{
_writemsg(logger, tokenizer, Location, "style", "C-style pointer casting");
_writemsg(logger, tokenizer, Location, "style", "C-style pointer casting", "cstyleCast");
}
static bool cstyleCast(const Settings &s)
{
@ -199,7 +199,7 @@ public:
static void redundantIfDelete0(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location)
{
_writemsg(logger, tokenizer, Location, "style", "Redundant condition. It is safe to deallocate a NULL pointer");
_writemsg(logger, tokenizer, Location, "style", "Redundant condition. It is safe to deallocate a NULL pointer", "redundantIfDelete0");
}
static bool redundantIfDelete0(const Settings &s)
{
@ -208,7 +208,7 @@ public:
static void redundantIfRemove(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location)
{
_writemsg(logger, tokenizer, Location, "style", "Redundant condition. The remove function in the STL will not do anything if element doesn't exist");
_writemsg(logger, tokenizer, Location, "style", "Redundant condition. The remove function in the STL will not do anything if element doesn't exist", "redundantIfRemove");
}
static bool redundantIfRemove(const Settings &s)
{
@ -217,7 +217,7 @@ public:
static void dangerousUsageStrtol(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location)
{
_writemsg(logger, tokenizer, Location, "always", "Invalid radix in call to strtol or strtoul. Must be 0 or 2-36");
_writemsg(logger, tokenizer, Location, "always", "Invalid radix in call to strtol or strtoul. Must be 0 or 2-36", "dangerousUsageStrtol");
}
static bool dangerousUsageStrtol()
{
@ -226,7 +226,7 @@ public:
static void ifNoAction(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location)
{
_writemsg(logger, tokenizer, Location, "style", "Found redundant if condition - 'if (condition);'");
_writemsg(logger, tokenizer, Location, "style", "Found redundant if condition - 'if (condition);'", "ifNoAction");
}
static bool ifNoAction(const Settings &s)
{
@ -235,7 +235,7 @@ public:
static void sprintfOverlappingData(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location, const std::string &varname)
{
_writemsg(logger, tokenizer, Location, "always", "Overlapping data buffer " + varname + "");
_writemsg(logger, tokenizer, Location, "always", "Overlapping data buffer " + varname + "", "sprintfOverlappingData");
}
static bool sprintfOverlappingData()
{
@ -244,7 +244,7 @@ public:
static void udivError(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location)
{
_writemsg(logger, tokenizer, Location, "always", "Unsigned division. The result will be wrong.");
_writemsg(logger, tokenizer, Location, "always", "Unsigned division. The result will be wrong.", "udivError");
}
static bool udivError()
{
@ -253,7 +253,7 @@ public:
static void udivWarning(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location)
{
_writemsg(logger, tokenizer, Location, "all style", "Warning: Division with signed and unsigned operators");
_writemsg(logger, tokenizer, Location, "all style", "Warning: Division with signed and unsigned operators", "udivWarning");
}
static bool udivWarning(const Settings &s)
{
@ -262,7 +262,7 @@ public:
static void unusedStructMember(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location, const std::string &structname, const std::string &varname)
{
_writemsg(logger, tokenizer, Location, "style", "struct or union member '" + structname + "::" + varname + "' is never used");
_writemsg(logger, tokenizer, Location, "style", "struct or union member '" + structname + "::" + varname + "' is never used", "unusedStructMember");
}
static bool unusedStructMember(const Settings &s)
{
@ -271,7 +271,7 @@ public:
static void passedByValue(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location, const std::string &parname)
{
_writemsg(logger, tokenizer, Location, "style", "Function parameter '" + parname + "' is passed by value. It could be passed by reference instead.");
_writemsg(logger, tokenizer, Location, "style", "Function parameter '" + parname + "' is passed by value. It could be passed by reference instead.", "passedByValue");
}
static bool passedByValue(const Settings &s)
{
@ -280,7 +280,7 @@ public:
static void constStatement(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location, const std::string &type)
{
_writemsg(logger, tokenizer, Location, "style", "Redundant code: Found a statement that begins with " + type + " constant");
_writemsg(logger, tokenizer, Location, "style", "Redundant code: Found a statement that begins with " + type + " constant", "constStatement");
}
static bool constStatement(const Settings &s)
{
@ -289,7 +289,7 @@ public:
static void charArrayIndex(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location)
{
_writemsg(logger, tokenizer, Location, "style", "Warning - using char variable as array index");
_writemsg(logger, tokenizer, Location, "style", "Warning - using char variable as array index", "charArrayIndex");
}
static bool charArrayIndex(const Settings &s)
{
@ -298,7 +298,7 @@ public:
static void charBitOp(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location)
{
_writemsg(logger, tokenizer, Location, "style", "Warning - using char variable in bit operation");
_writemsg(logger, tokenizer, Location, "style", "Warning - using char variable in bit operation", "charBitOp");
}
static bool charBitOp(const Settings &s)
{
@ -307,7 +307,7 @@ public:
static void variableScope(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location, const std::string &varname)
{
_writemsg(logger, tokenizer, Location, "never", "The scope of the variable " + varname + " can be limited");
_writemsg(logger, tokenizer, Location, "never", "The scope of the variable " + varname + " can be limited", "variableScope");
}
static bool variableScope()
{
@ -316,7 +316,7 @@ public:
static void conditionAlwaysTrueFalse(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location, const std::string &truefalse)
{
_writemsg(logger, tokenizer, Location, "style", "Condition is always " + truefalse + "");
_writemsg(logger, tokenizer, Location, "style", "Condition is always " + truefalse + "", "conditionAlwaysTrueFalse");
}
static bool conditionAlwaysTrueFalse(const Settings &s)
{
@ -325,7 +325,7 @@ public:
static void strPlusChar(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location)
{
_writemsg(logger, tokenizer, Location, "always", "Unusual pointer arithmetic");
_writemsg(logger, tokenizer, Location, "always", "Unusual pointer arithmetic", "strPlusChar");
}
static bool strPlusChar()
{

View File

@ -27,7 +27,7 @@ Settings::Settings()
_errorsOnly = false;
_verbose = false;
_force = false;
_xmlResults = false;
_xml = false;
_unusedFunctions = false;
}

View File

@ -40,8 +40,8 @@ public:
/** Force checking t he files with "too many" configurations. */
bool _force;
/** write results in xml file results.xml */
bool _xmlResults;
/** write xml results */
bool _xml;
/** Checking if there are unused functions */
bool _unusedFunctions;

View File

@ -177,3 +177,8 @@ void TestFixture::reportOut(const std::string & /*outmsg*/)
{
// These can probably be ignored
}
void TestFixture::reportXml(const std::string & /*file*/, const std::string & /*line*/, const std::string & /*id*/, const std::string & /*severity*/, const std::string & /*msg*/)
{
// These can probably be ignored
}

View File

@ -43,8 +43,8 @@ protected:
public:
virtual void reportErr(const std::string &errmsg);
virtual void reportOut(const std::string &outmsg);
virtual void reportXml(const std::string &file, const std::string &line, const std::string &id, const std::string &severity, const std::string &msg);
void run(const std::string &str);

View File

@ -138,9 +138,9 @@ int main()
fout << "{\n";
fout << "private:\n";
fout << " ErrorMessage() { }\n";
fout << " static void _writemsg(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *tok, const char severity[], const std::string msg);\n";
fout << " static void _writemsg(ErrorLogger *logger, const Tokenizer *tokenizer, const std::list<const Token *> &callstack, const char severity[], const std::string msg);\n";
fout << " static void _writemsg(ErrorLogger *logger, const std::string msg);\n";
fout << " static void _writemsg(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *tok, const char severity[], const std::string msg, const std::string &id);\n";
fout << " static void _writemsg(ErrorLogger *logger, const Tokenizer *tokenizer, const std::list<const Token *> &callstack, const char severity[], const std::string msg, const std::string &id);\n";
fout << " static void _writemsg(ErrorLogger *logger, const std::string msg, const std::string &id);\n";
fout << "public:\n";
for (std::list<Message>::const_iterator it = err.begin(); it != err.end(); ++it)
it->generateCode(fout);
@ -246,7 +246,7 @@ void Message::generateCode(std::ostream &ostr) const
ostr << " _writemsg(logger, ";
if (loc)
ostr << "tokenizer, Location, \"" << stringifySettings(true) << "\", ";
ostr << msg(true) << ");\n";
ostr << msg(true) << ", \"" << _funcname << "\");\n";
/*
ostr << " return ";
if (loc)