Multicore cpu support for Linux (currently disabled and compiling produces warnings)
"no errors" output removed.
This commit is contained in:
parent
efeaac736d
commit
4fc774deda
7
Makefile
7
Makefile
|
@ -20,6 +20,7 @@ OBJECTS = src/checkbufferoverrun.o \
|
|||
src/main.o \
|
||||
src/preprocessor.o \
|
||||
src/settings.o \
|
||||
src/threadexecutor.o \
|
||||
src/token.o \
|
||||
src/tokenize.o
|
||||
|
||||
|
@ -62,6 +63,7 @@ TESTOBJ = test/testbufferoverrun.o \
|
|||
src/filelister.o \
|
||||
src/preprocessor.o \
|
||||
src/settings.o \
|
||||
src/threadexecutor.o \
|
||||
src/token.o \
|
||||
src/tokenize.o
|
||||
|
||||
|
@ -127,7 +129,7 @@ src/checkvalidate.o: src/checkvalidate.cpp src/checkvalidate.h src/errorlogger.h
|
|||
src/cppcheck.o: src/cppcheck.cpp src/cppcheck.h src/settings.h src/errorlogger.h src/checkfunctionusage.h src/tokenize.h src/token.h src/preprocessor.h src/checkmemoryleak.h src/checkbufferoverrun.h src/checkdangerousfunctions.h src/checkclass.h src/checkheaders.h src/checkother.h src/checkstl.h src/filelister.h
|
||||
g++ $(CXXFLAGS) -c -o src/cppcheck.o src/cppcheck.cpp
|
||||
|
||||
src/cppcheckexecutor.o: src/cppcheckexecutor.cpp src/cppcheckexecutor.h src/errorlogger.h src/settings.h src/cppcheck.h src/checkfunctionusage.h src/tokenize.h src/token.h
|
||||
src/cppcheckexecutor.o: src/cppcheckexecutor.cpp src/cppcheckexecutor.h src/errorlogger.h src/settings.h src/cppcheck.h src/checkfunctionusage.h src/tokenize.h src/token.h src/threadexecutor.h
|
||||
g++ $(CXXFLAGS) -c -o src/cppcheckexecutor.o src/cppcheckexecutor.cpp
|
||||
|
||||
src/errorlogger.o: src/errorlogger.cpp src/errorlogger.h src/settings.h src/tokenize.h src/token.h
|
||||
|
@ -145,6 +147,9 @@ src/preprocessor.o: src/preprocessor.cpp src/preprocessor.h src/tokenize.h src/s
|
|||
src/settings.o: src/settings.cpp src/settings.h
|
||||
g++ $(CXXFLAGS) -c -o src/settings.o src/settings.cpp
|
||||
|
||||
src/threadexecutor.o: src/threadexecutor.cpp src/threadexecutor.h src/settings.h src/errorlogger.h src/cppcheck.h src/checkfunctionusage.h src/tokenize.h src/token.h
|
||||
g++ $(CXXFLAGS) -c -o src/threadexecutor.o src/threadexecutor.cpp
|
||||
|
||||
src/token.o: src/token.cpp src/token.h
|
||||
g++ $(CXXFLAGS) -c -o src/token.o src/token.cpp
|
||||
|
||||
|
|
|
@ -59,6 +59,8 @@
|
|||
<Unit filename="src/preprocessor.h" />
|
||||
<Unit filename="src/settings.cpp" />
|
||||
<Unit filename="src/settings.h" />
|
||||
<Unit filename="src/threadexecutor.cpp" />
|
||||
<Unit filename="src/threadexecutor.h" />
|
||||
<Unit filename="src/token.cpp" />
|
||||
<Unit filename="src/token.h" />
|
||||
<Unit filename="src/tokenize.cpp" />
|
||||
|
|
|
@ -262,16 +262,7 @@ unsigned int CppCheck::check()
|
|||
++checkCount;
|
||||
}
|
||||
|
||||
if (_settings._errorsOnly == false && _errout.str().empty())
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "No errors found ("
|
||||
<< (c + 1) << "/" << _filenames.size()
|
||||
<< " files checked " <<
|
||||
static_cast<int>(static_cast<double>((c + 1)) / _filenames.size()*100)
|
||||
<< "% done)";
|
||||
_errorLogger->reportOut(oss.str());
|
||||
}
|
||||
_errorLogger->reportStatus(c + 1, _filenames.size());
|
||||
}
|
||||
|
||||
// This generates false positives - especially for libraries
|
||||
|
@ -458,3 +449,13 @@ void CppCheck::reportOut(const std::string & /*outmsg*/)
|
|||
// This is currently never called. It is here just to comply with
|
||||
// the interface.
|
||||
}
|
||||
|
||||
const std::vector<std::string> &CppCheck::filenames() const
|
||||
{
|
||||
return _filenames;
|
||||
}
|
||||
|
||||
void CppCheck::reportStatus(unsigned int /*index*/, unsigned int /*max*/)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -100,6 +100,10 @@ public:
|
|||
*/
|
||||
std::string parseFromArgs(int argc, const char* const argv[]);
|
||||
|
||||
const std::vector<std::string> &filenames() const;
|
||||
|
||||
virtual void reportStatus(unsigned int index, unsigned int max);
|
||||
|
||||
private:
|
||||
void checkFile(const std::string &code, const char FileName[]);
|
||||
|
||||
|
|
|
@ -19,17 +19,18 @@
|
|||
|
||||
#include "cppcheckexecutor.h"
|
||||
#include "cppcheck.h"
|
||||
#include "threadexecutor.h"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
CppCheckExecutor::CppCheckExecutor()
|
||||
{
|
||||
_useXML = false;
|
||||
|
||||
}
|
||||
|
||||
CppCheckExecutor::~CppCheckExecutor()
|
||||
{
|
||||
//dtor
|
||||
|
||||
}
|
||||
|
||||
unsigned int CppCheckExecutor::check(int argc, const char* const argv[])
|
||||
|
@ -38,15 +39,29 @@ unsigned int CppCheckExecutor::check(int argc, const char* const argv[])
|
|||
std::string result = cppCheck.parseFromArgs(argc, argv);
|
||||
if (result.length() == 0)
|
||||
{
|
||||
if (cppCheck.settings()._xml)
|
||||
_settings = cppCheck.settings();
|
||||
if (_settings._xml)
|
||||
{
|
||||
_useXML = true;
|
||||
reportErr("<?xml version=\"1.0\"?>");
|
||||
reportErr("<results>");
|
||||
}
|
||||
|
||||
unsigned int returnValue = cppCheck.check();
|
||||
if (_useXML)
|
||||
unsigned int returnValue = 0;
|
||||
if (1)
|
||||
{
|
||||
// Single process
|
||||
returnValue = cppCheck.check();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Multiple processes
|
||||
const std::vector<std::string> &filenames = cppCheck.filenames();
|
||||
Settings settings = cppCheck.settings();
|
||||
ThreadExecutor executor(filenames, settings, *this);
|
||||
returnValue = executor.check();
|
||||
}
|
||||
|
||||
if (_settings._xml)
|
||||
{
|
||||
reportErr("</results>");
|
||||
}
|
||||
|
@ -70,9 +85,22 @@ void CppCheckExecutor::reportOut(const std::string &outmsg)
|
|||
std::cout << outmsg << std::endl;
|
||||
}
|
||||
|
||||
void CppCheckExecutor::reportStatus(unsigned int index, unsigned int max)
|
||||
{
|
||||
if (max > 1 && !_settings._errorsOnly)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << index << "/" << max
|
||||
<< " files checked " <<
|
||||
static_cast<int>(static_cast<double>(index) / max*100)
|
||||
<< "% done";
|
||||
std::cout << oss.str() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void CppCheckExecutor::reportErr(const ErrorLogger::ErrorMessage &msg)
|
||||
{
|
||||
if (_useXML)
|
||||
if (_settings._xml)
|
||||
{
|
||||
reportErr(msg.toXML());
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#define CPPCHECKEXECUTOR_H
|
||||
|
||||
#include "errorlogger.h"
|
||||
#include "settings.h"
|
||||
|
||||
/**
|
||||
* This class works as an example of how CppCheck can be used in external
|
||||
|
@ -67,6 +68,8 @@ public:
|
|||
/** xml output of errors */
|
||||
virtual void reportErr(const ErrorLogger::ErrorMessage &msg);
|
||||
|
||||
virtual void reportStatus(unsigned int index, unsigned int max);
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
|
@ -75,7 +78,7 @@ private:
|
|||
*/
|
||||
void reportErr(const std::string &errmsg);
|
||||
|
||||
bool _useXML;
|
||||
Settings _settings;
|
||||
};
|
||||
|
||||
#endif // CPPCHECKEXECUTOR_H
|
||||
|
|
|
@ -23,6 +23,11 @@
|
|||
|
||||
#include <sstream>
|
||||
|
||||
ErrorLogger::ErrorMessage::ErrorMessage()
|
||||
{
|
||||
|
||||
}
|
||||
#include <iostream>
|
||||
ErrorLogger::ErrorMessage::ErrorMessage(const std::list<FileLocation> &callStack, const std::string &severity, const std::string &msg, const std::string &id)
|
||||
{
|
||||
_callStack = callStack;
|
||||
|
@ -31,6 +36,78 @@ ErrorLogger::ErrorMessage::ErrorMessage(const std::list<FileLocation> &callStack
|
|||
_id = id;
|
||||
}
|
||||
|
||||
std::string ErrorLogger::ErrorMessage::serialize() const
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << _id.length() << " " << _id;
|
||||
oss << _severity.length() << " " << _severity;
|
||||
oss << _msg.length() << " " << _msg;
|
||||
oss << _callStack.size() << " ";
|
||||
|
||||
for (std::list<ErrorLogger::ErrorMessage::FileLocation>::const_iterator tok = _callStack.begin(); tok != _callStack.end(); ++tok)
|
||||
{
|
||||
std::ostringstream smallStream;
|
||||
smallStream << (*tok).line << ":" << (*tok).file;
|
||||
oss << smallStream.str().length() << " " << smallStream.str();
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
bool ErrorLogger::ErrorMessage::deserialize(const std::string &data)
|
||||
{
|
||||
_callStack.clear();
|
||||
std::istringstream iss(data);
|
||||
std::vector<std::string> results;
|
||||
while (iss.good())
|
||||
{
|
||||
unsigned int len = 0;
|
||||
if (!(iss >> len))
|
||||
return false;
|
||||
|
||||
iss.get();
|
||||
std::string temp;
|
||||
for (unsigned int i = 0; i < len && iss.good(); ++i)
|
||||
temp.append(1, iss.get());
|
||||
|
||||
results.push_back(temp);
|
||||
if (results.size() == 3)
|
||||
break;
|
||||
}
|
||||
|
||||
_id = results[0];
|
||||
_severity = results[1];
|
||||
_msg = results[2];
|
||||
|
||||
unsigned int stackSize = 0;
|
||||
if (!(iss >> stackSize))
|
||||
return false;
|
||||
|
||||
while (iss.good())
|
||||
{
|
||||
unsigned int len = 0;
|
||||
if (!(iss >> len))
|
||||
return false;
|
||||
|
||||
iss.get();
|
||||
std::string temp;
|
||||
for (unsigned int i = 0; i < len && iss.good(); ++i)
|
||||
temp.append(1, iss.get());
|
||||
|
||||
ErrorLogger::ErrorMessage::FileLocation loc;
|
||||
loc.file = temp.substr(temp.find(':') + 1);
|
||||
temp = temp.substr(0, temp.find(':'));
|
||||
std::istringstream fiss(temp);
|
||||
fiss >> loc.line;
|
||||
|
||||
_callStack.push_back(loc);
|
||||
|
||||
if (_callStack.size() >= stackSize)
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string ErrorLogger::ErrorMessage::toXML() const
|
||||
{
|
||||
std::ostringstream xml;
|
||||
|
|
|
@ -52,8 +52,11 @@ public:
|
|||
};
|
||||
|
||||
ErrorMessage(const std::list<FileLocation> &callStack, const std::string &severity, const std::string &msg, const std::string &id);
|
||||
ErrorMessage();
|
||||
std::string toXML() const;
|
||||
std::string toText() const;
|
||||
std::string serialize() const;
|
||||
bool deserialize( const std::string &data );
|
||||
private:
|
||||
std::list<FileLocation> _callStack;
|
||||
std::string _severity;
|
||||
|
@ -81,6 +84,14 @@ public:
|
|||
*/
|
||||
virtual void reportErr(const ErrorLogger::ErrorMessage &msg) = 0;
|
||||
|
||||
/**
|
||||
* Information about how many files have been checked
|
||||
*
|
||||
* @param index This many files have been checked.
|
||||
* @param max This many files there are in total.
|
||||
*/
|
||||
virtual void reportStatus(unsigned int index, unsigned int max) = 0;
|
||||
|
||||
void arrayIndexOutOfBounds(const Tokenizer *tokenizer, const std::list<const Token *> &Location)
|
||||
{
|
||||
_writemsg(tokenizer, Location, "all", "Array index out of bounds", "arrayIndexOutOfBounds");
|
||||
|
|
|
@ -0,0 +1,191 @@
|
|||
/*
|
||||
* Cppcheck - A tool for static C/C++ code analysis
|
||||
* Copyright (C) 2007-2009 Daniel Marjamäki, Reijo Tomperi, Nicolas Le Cam,
|
||||
* Leandro Penz, Kimmo Varis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/
|
||||
*/
|
||||
|
||||
#include "threadexecutor.h"
|
||||
#include "cppcheck.h"
|
||||
|
||||
#if 0
|
||||
|
||||
/**
|
||||
This implementation is currently for Linux only and disabled with #if 0 until
|
||||
proper way is invented.
|
||||
*/
|
||||
|
||||
#include <sys/wait.h>
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
ThreadExecutor::ThreadExecutor(const std::vector<std::string> &filenames, const Settings &settings, ErrorLogger &errorLogger)
|
||||
: _filenames(filenames), _settings(settings), _errorLogger(errorLogger), _fileCount(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ThreadExecutor::~ThreadExecutor()
|
||||
{
|
||||
//dtor
|
||||
}
|
||||
|
||||
bool ThreadExecutor::handleRead(unsigned int &result)
|
||||
{
|
||||
char type = 0;
|
||||
if (read(_pipe[0], &type, 1) <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (type != '1' && type != '2' && type != '3')
|
||||
{
|
||||
std::cerr << "#### ThreadExecutor::handleRead error, type was:" << type << std::endl;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
unsigned int len = 0;
|
||||
read(_pipe[0], &len, sizeof(len));
|
||||
char *buf = new char[len];
|
||||
read(_pipe[0], buf, len);
|
||||
if (type == '1')
|
||||
{
|
||||
_errorLogger.reportOut(buf);
|
||||
}
|
||||
else if (type == '2')
|
||||
{
|
||||
ErrorLogger::ErrorMessage msg;
|
||||
msg.deserialize(buf);
|
||||
_errorLogger.reportErr(msg);
|
||||
}
|
||||
else if (type == '3')
|
||||
{
|
||||
_fileCount++;
|
||||
std::istringstream iss(buf);
|
||||
unsigned int fileResult = 0;
|
||||
iss >> fileResult;
|
||||
result += fileResult;
|
||||
_errorLogger.reportStatus(_fileCount, _filenames.size());
|
||||
}
|
||||
|
||||
delete [] buf;
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned int ThreadExecutor::check()
|
||||
{
|
||||
_fileCount = 0;
|
||||
unsigned int result = 0;
|
||||
if (pipe(_pipe) == -1)
|
||||
{
|
||||
perror("pipe");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int flags = 0;
|
||||
if ((flags = fcntl(_pipe[0], F_GETFL, 0)) < 0)
|
||||
{
|
||||
perror("fcntl");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (fcntl(_pipe[0], F_SETFL, flags | O_NONBLOCK) < 0)
|
||||
{
|
||||
perror("fcntl");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
unsigned int childCount = 0;
|
||||
for (unsigned int i = 0; i < _filenames.size(); i++)
|
||||
{
|
||||
// Keep only wanted amount of child processes running at a time.
|
||||
if (childCount >= 2)
|
||||
{
|
||||
while (handleRead(result))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int stat = 0;
|
||||
waitpid(0, &stat, 0);
|
||||
--childCount;
|
||||
}
|
||||
|
||||
pid_t pid = fork();
|
||||
if (pid < 0)
|
||||
{
|
||||
// Error
|
||||
std::cerr << "Failed to create child process" << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else if (pid == 0)
|
||||
{
|
||||
CppCheck fileChecker(*this);
|
||||
fileChecker.settings(_settings);
|
||||
fileChecker.addFile(_filenames[i]);
|
||||
unsigned int result = fileChecker.check();
|
||||
std::ostringstream oss;
|
||||
oss << result;
|
||||
writeToPipe('3', oss.str());
|
||||
exit(0);
|
||||
}
|
||||
|
||||
++childCount;
|
||||
}
|
||||
|
||||
while (childCount > 0)
|
||||
{
|
||||
int stat = 0;
|
||||
waitpid(0, &stat, 0);
|
||||
--childCount;
|
||||
}
|
||||
|
||||
while (handleRead(result))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void ThreadExecutor::writeToPipe(char type, const std::string &data)
|
||||
{
|
||||
unsigned int len = data.length() + 1;
|
||||
char *out = new char[ len + 1 + sizeof(len)];
|
||||
out[0] = type;
|
||||
memcpy(&(out[1]), &len, sizeof(len));
|
||||
memcpy(&(out[1+sizeof(len)]), data.c_str(), len);
|
||||
write(_pipe[1], out, len + 1 + sizeof(len));
|
||||
}
|
||||
|
||||
void ThreadExecutor::reportOut(const std::string &outmsg)
|
||||
{
|
||||
writeToPipe('1', outmsg);
|
||||
}
|
||||
|
||||
void ThreadExecutor::reportErr(const ErrorLogger::ErrorMessage &msg)
|
||||
{
|
||||
writeToPipe('2', msg.serialize());
|
||||
}
|
||||
|
||||
void ThreadExecutor::reportStatus(unsigned int /*index*/, unsigned int /*max*/)
|
||||
{
|
||||
// Not used
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#endif
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Cppcheck - A tool for static C/C++ code analysis
|
||||
* Copyright (C) 2007-2009 Daniel Marjamäki, Reijo Tomperi, Nicolas Le Cam,
|
||||
* Leandro Penz, Kimmo Varis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/
|
||||
*/
|
||||
|
||||
#ifndef THREADEXECUTOR_H
|
||||
#define THREADEXECUTOR_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "settings.h"
|
||||
#include "errorlogger.h"
|
||||
|
||||
/**
|
||||
* This class will take a list of filenames and settings and check then
|
||||
* all files using threads.
|
||||
*/
|
||||
class ThreadExecutor : public ErrorLogger
|
||||
{
|
||||
#if 0
|
||||
public:
|
||||
ThreadExecutor(const std::vector<std::string> &filenames, const Settings &settings, ErrorLogger &_errorLogger);
|
||||
virtual ~ThreadExecutor();
|
||||
unsigned int check();
|
||||
virtual void reportOut(const std::string &outmsg);
|
||||
virtual void reportErr(const ErrorLogger::ErrorMessage &msg);
|
||||
virtual void reportStatus(unsigned int index, unsigned int max);
|
||||
protected:
|
||||
private:
|
||||
bool handleRead(unsigned int &result);
|
||||
void writeToPipe(char type, const std::string &data);
|
||||
|
||||
const std::vector<std::string> &_filenames;
|
||||
const Settings &_settings;
|
||||
ErrorLogger &_errorLogger;
|
||||
int _pipe[2];
|
||||
unsigned int _fileCount;
|
||||
#else
|
||||
public:
|
||||
ThreadExecutor(const std::vector<std::string> &filenames, const Settings &settings, ErrorLogger &_errorLogger) {};
|
||||
virtual ~ThreadExecutor() {};
|
||||
unsigned int check()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
virtual void reportOut(const std::string &outmsg) {}
|
||||
virtual void reportErr(const ErrorLogger::ErrorMessage &msg) {}
|
||||
virtual void reportStatus(unsigned int index, unsigned int max) {}
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // THREADEXECUTOR_H
|
|
@ -44,7 +44,7 @@ protected:
|
|||
public:
|
||||
virtual void reportOut(const std::string &outmsg);
|
||||
virtual void reportErr(const ErrorLogger::ErrorMessage &msg);
|
||||
|
||||
virtual void reportStatus(unsigned int /*index*/, unsigned int /*max*/) {}
|
||||
void run(const std::string &str);
|
||||
|
||||
TestFixture(const std::string &_name);
|
||||
|
|
|
@ -177,8 +177,11 @@ int main()
|
|||
fout << " };\n";
|
||||
fout << "\n";
|
||||
fout << " ErrorMessage(const std::list<FileLocation> &callStack, const std::string &severity, const std::string &msg, const std::string &id);\n";
|
||||
fout << " ErrorMessage();\n";
|
||||
fout << " std::string toXML() const;\n";
|
||||
fout << " std::string toText() const;\n";
|
||||
fout << " std::string serialize() const;\n";
|
||||
fout << " bool deserialize( const std::string &data );\n";
|
||||
fout << " private:\n";
|
||||
fout << " std::list<FileLocation> _callStack;\n";
|
||||
fout << " std::string _severity;\n";
|
||||
|
@ -206,6 +209,14 @@ int main()
|
|||
fout << " */\n";
|
||||
fout << " virtual void reportErr(const ErrorLogger::ErrorMessage &msg) = 0;\n";
|
||||
fout << "\n";
|
||||
fout << " /**\n";
|
||||
fout << " * Information about how many files have been checked\n";
|
||||
fout << " *\n";
|
||||
fout << " * @param index This many files have been checked.\n";
|
||||
fout << " * @param max This many files there are in total.\n";
|
||||
fout << " */\n";
|
||||
fout << " virtual void reportStatus(unsigned int index, unsigned int max) = 0;\n";
|
||||
fout << "\n";
|
||||
|
||||
for (std::list<Message>::const_iterator it = err.begin(); it != err.end(); ++it)
|
||||
it->generateCode(fout);
|
||||
|
|
Loading…
Reference in New Issue