Merge branch 'single-file-check'

This commit is contained in:
Kimmo Varis 2011-04-25 15:31:46 +03:00
commit ce29342661
7 changed files with 162 additions and 180 deletions

View File

@ -114,7 +114,7 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c
{ {
std::vector<std::string>::iterator iter; std::vector<std::string>::iterator iter;
for (iter = filenames.begin(); iter != filenames.end(); ++iter) for (iter = filenames.begin(); iter != filenames.end(); ++iter)
cppcheck->addFile(*iter); _filenames.push_back(*iter);
return true; return true;
} }
@ -146,7 +146,11 @@ int CppCheckExecutor::check(int argc, const char* const argv[])
if (_settings._jobs == 1) if (_settings._jobs == 1)
{ {
// Single process // Single process
returnValue = cppCheck.check(); for (unsigned int c = 0; c < _filenames.size(); c++)
{
returnValue += cppCheck.check(_filenames[c]);
reportStatus(c + 1, _filenames.size());
}
} }
else if (!ThreadExecutor::isEnabled()) else if (!ThreadExecutor::isEnabled())
{ {
@ -155,9 +159,8 @@ int CppCheckExecutor::check(int argc, const char* const argv[])
else else
{ {
// Multiple processes // Multiple processes
const std::vector<std::string> &filenames = cppCheck.filenames();
Settings &settings = cppCheck.settings(); Settings &settings = cppCheck.settings();
ThreadExecutor executor(filenames, settings, *this); ThreadExecutor executor(_filenames, settings, *this);
returnValue = executor.check(); returnValue = executor.check();
} }

View File

@ -22,6 +22,7 @@
#include "errorlogger.h" #include "errorlogger.h"
#include "settings.h" #include "settings.h"
#include <ctime> #include <ctime>
#include <vector>
class CppCheck; class CppCheck;
@ -107,6 +108,11 @@ private:
* Has --errorlist been given? * Has --errorlist been given?
*/ */
bool errorlist; bool errorlist;
/**
* List of files to check.
*/
std::vector<std::string> _filenames;
}; };
#endif // CPPCHECKEXECUTOR_H #endif // CPPCHECKEXECUTOR_H

View File

@ -177,19 +177,19 @@ unsigned int ThreadExecutor::check()
CppCheck fileChecker(*this, false); CppCheck fileChecker(*this, false);
fileChecker.settings(_settings); fileChecker.settings(_settings);
unsigned int resultOfCheck = 0;
if (_fileContents.size() > 0 && _fileContents.find(_filenames[i]) != _fileContents.end()) if (_fileContents.size() > 0 && _fileContents.find(_filenames[i]) != _fileContents.end())
{ {
// File content was given as a string // File content was given as a string
fileChecker.addFile(_filenames[i], _fileContents[ _filenames[i] ]); resultOfCheck = fileChecker.check(_filenames[i], _fileContents[ _filenames[i] ]);
} }
else else
{ {
// Read file from a file // Read file from a file
fileChecker.addFile(_filenames[i]); resultOfCheck = fileChecker.check(_filenames[i]);
} }
unsigned int resultOfCheck = fileChecker.check();
std::ostringstream oss; std::ostringstream oss;
oss << resultOfCheck; oss << resultOfCheck;
writeToPipe('3', oss.str()); writeToPipe('3', oss.str());

View File

@ -50,9 +50,7 @@ void CheckThread::run()
while (!file.isEmpty() && mState == Running) while (!file.isEmpty() && mState == Running)
{ {
qDebug() << "Checking file" << file; qDebug() << "Checking file" << file;
mCppcheck.addFile(file.toStdString()); mCppcheck.check(file.toStdString());
mCppcheck.check();
mCppcheck.clearFiles();
emit FileChecked(file); emit FileChecked(file);
if (mState == Running) if (mState == Running)

View File

@ -54,63 +54,49 @@ void CppCheck::settings(const Settings &currentSettings)
_settings = currentSettings; _settings = currentSettings;
} }
void CppCheck::addFile(const std::string &filepath)
{
_filenames.push_back(Path::fromNativeSeparators(filepath));
}
void CppCheck::addFile(const std::string &path, const std::string &content)
{
_filenames.push_back(Path::fromNativeSeparators(path));
_fileContents[ path ] = content;
}
void CppCheck::clearFiles()
{
_filenames.clear();
_fileContents.clear();
}
const char * CppCheck::version() const char * CppCheck::version()
{ {
return "1.48"; return "1.48";
} }
unsigned int CppCheck::check() unsigned int CppCheck::check(const std::string &path)
{
_filename = path;
return processFile();
}
unsigned int CppCheck::check(const std::string &path, const std::string &content)
{
_filename = path;
_fileContent = content;
const unsigned int retval = processFile();
_fileContent.clear();
return retval;
}
unsigned int CppCheck::processFile()
{ {
exitcode = 0; exitcode = 0;
std::sort(_filenames.begin(), _filenames.end());
// TODO: Should this be moved out to its own function so all the files can be // TODO: Should this be moved out to its own function so all the files can be
// analysed before any files are checked? // analysed before any files are checked?
if (_settings.test_2_pass && _settings._jobs == 1) if (_settings.test_2_pass && _settings._jobs == 1)
{ {
for (unsigned int c = 0; c < _filenames.size(); c++) const std::string printname = Path::toNativeSeparators(_filename);
{ reportOut("Analysing " + printname + "...");
const std::string fname = _filenames[c];
if (_settings.terminated())
break;
std::string fixedname = Path::toNativeSeparators(fname); std::ifstream f(_filename.c_str());
reportOut("Analysing " + fixedname + ".."); analyseFile(f, _filename);
std::ifstream f(fname.c_str());
analyseFile(f, fname);
}
} }
for (unsigned int c = 0; c < _filenames.size(); c++)
{
_errout.str(""); _errout.str("");
const std::string fname = _filenames[c];
if (_settings.terminated()) if (_settings.terminated())
break; return exitcode;
if (_settings._errorsOnly == false) if (_settings._errorsOnly == false)
{ {
std::string fixedpath(fname); std::string fixedpath(_filename);
fixedpath = Path::simplifyPath(fixedpath.c_str()); fixedpath = Path::simplifyPath(fixedpath.c_str());
fixedpath = Path::toNativeSeparators(fixedpath); fixedpath = Path::toNativeSeparators(fixedpath);
_errorLogger.reportOut(std::string("Checking ") + fixedpath + std::string("...")); _errorLogger.reportOut(std::string("Checking ") + fixedpath + std::string("..."));
@ -122,18 +108,18 @@ unsigned int CppCheck::check()
std::list<std::string> configurations; std::list<std::string> configurations;
std::string filedata = ""; std::string filedata = "";
if ((!_fileContents.empty()) && (_fileContents.find(_filenames[c]) != _fileContents.end())) if (!_fileContent.empty())
{ {
// File content was given as a string // File content was given as a string
std::istringstream iss(_fileContents[ _filenames[c] ]); std::istringstream iss(_fileContent);
preprocessor.preprocess(iss, filedata, configurations, fname, _settings._includePaths); preprocessor.preprocess(iss, filedata, configurations, _filename, _settings._includePaths);
} }
else else
{ {
// Only file name was given, read the content from file // Only file name was given, read the content from file
std::ifstream fin(fname.c_str()); std::ifstream fin(_filename.c_str());
Timer t("Preprocessor::preprocess", _settings._showtime, &S_timerResults); Timer t("Preprocessor::preprocess", _settings._showtime, &S_timerResults);
preprocessor.preprocess(fin, filedata, configurations, fname, _settings._includePaths); preprocessor.preprocess(fin, filedata, configurations, _filename, _settings._includePaths);
} }
_settings.ifcfg = bool(configurations.size() > 1); _settings.ifcfg = bool(configurations.size() > 1);
@ -151,7 +137,7 @@ unsigned int CppCheck::check()
// was used. // was used.
if (!_settings._force && checkCount > 11) if (!_settings._force && checkCount > 11)
{ {
const std::string fixedpath = Path::toNativeSeparators(fname); const std::string fixedpath = Path::toNativeSeparators(_filename);
ErrorLogger::ErrorMessage::FileLocation location; ErrorLogger::ErrorMessage::FileLocation location;
location.setfile(fixedpath); location.setfile(fixedpath);
std::list<ErrorLogger::ErrorMessage::FileLocation> loclist; std::list<ErrorLogger::ErrorMessage::FileLocation> loclist;
@ -172,13 +158,13 @@ unsigned int CppCheck::check()
cfg = *it; cfg = *it;
Timer t("Preprocessor::getcode", _settings._showtime, &S_timerResults); Timer t("Preprocessor::getcode", _settings._showtime, &S_timerResults);
const std::string codeWithoutCfg = Preprocessor::getcode(filedata, *it, fname, &_settings, &_errorLogger); const std::string codeWithoutCfg = Preprocessor::getcode(filedata, *it, _filename, &_settings, &_errorLogger);
t.Stop(); t.Stop();
// If only errors are printed, print filename after the check // If only errors are printed, print filename after the check
if (_settings._errorsOnly == false && it != configurations.begin()) if (_settings._errorsOnly == false && it != configurations.begin())
{ {
std::string fixedpath = Path::simplifyPath(fname.c_str()); std::string fixedpath = Path::simplifyPath(_filename.c_str());
fixedpath = Path::toNativeSeparators(fixedpath); fixedpath = Path::toNativeSeparators(fixedpath);
_errorLogger.reportOut(std::string("Checking ") + fixedpath + ": " + cfg + std::string("...")); _errorLogger.reportOut(std::string("Checking ") + fixedpath + ": " + cfg + std::string("..."));
} }
@ -187,21 +173,18 @@ unsigned int CppCheck::check()
if (!appendCode.empty()) if (!appendCode.empty())
Preprocessor::preprocessWhitespaces(appendCode); Preprocessor::preprocessWhitespaces(appendCode);
checkFile(codeWithoutCfg + appendCode, _filenames[c].c_str()); checkFile(codeWithoutCfg + appendCode, _filename.c_str());
++checkCount; ++checkCount;
} }
} }
catch (std::runtime_error &e) catch (std::runtime_error &e)
{ {
// Exception was thrown when checking this file.. // Exception was thrown when checking this file..
const std::string fixedpath = Path::toNativeSeparators(fname); const std::string fixedpath = Path::toNativeSeparators(_filename);
_errorLogger.reportOut("Bailing out from checking " + fixedpath + ": " + e.what()); _errorLogger.reportOut("Bailing out from checking " + fixedpath + ": " + e.what());
} }
reportUnmatchedSuppressions(_settings.nomsg.getUnmatchedLocalSuppressions(fname)); reportUnmatchedSuppressions(_settings.nomsg.getUnmatchedLocalSuppressions(_filename));
_errorLogger.reportStatus(c + 1, (unsigned int)_filenames.size());
}
// This generates false positives - especially for libraries // This generates false positives - especially for libraries
const bool verbose_orig = _settings._verbose; const bool verbose_orig = _settings._verbose;
@ -445,11 +428,6 @@ void CppCheck::reportOut(const std::string &outmsg)
_errorLogger.reportOut(outmsg); _errorLogger.reportOut(outmsg);
} }
const std::vector<std::string> &CppCheck::filenames() const
{
return _filenames;
}
void CppCheck::reportProgress(const std::string &filename, const char stage[], const unsigned int value) void CppCheck::reportProgress(const std::string &filename, const char stage[], const unsigned int value)
{ {
_errorLogger.reportProgress(filename, stage, value); _errorLogger.reportProgress(filename, stage, value);

View File

@ -55,7 +55,29 @@ public:
* parseFromArgs() or settings() and addFile() before calling this. * parseFromArgs() or settings() and addFile() before calling this.
* @return amount of errors found or 0 if none were found. * @return amount of errors found or 0 if none were found.
*/ */
unsigned int check();
/**
* @brief Check the file.
* This function checks one given file for errors.
* @param path Path to the file to check.
* @return amount of errors found or 0 if none were found.
* @note You must set settings before calling this function (by calling
* settings()).
*/
unsigned int check(const std::string &path);
/**
* @brief Check the file.
* This function checks one "virtual" file. The file is not read from
* the disk but the content is given in @p content. In errors the @p path
* is used as a filename.
* @param path Path to the file to check.
* @param content File content as a string.
* @return amount of errors found or 0 if none were found.
* @note You must set settings before calling this function (by calling
* settings()).
*/
unsigned int check(const std::string &path, const std::string &content);
/** /**
* @brief Adjust the settings before doing the check. E.g. show only * @brief Adjust the settings before doing the check. E.g. show only
@ -71,37 +93,12 @@ public:
*/ */
Settings &settings(); Settings &settings();
/**
* @brief Add new file to be checked.
*
* @param filepath Relative or absolute path to the file to be checked,
* e.g. "cppcheck.cpp". Note that only source files (.c, .cc or .cpp)
* should be added to the list. Include files are gathered automatically.
*/
void addFile(const std::string &filepath);
/**
* @brief Add new unreal file to be checked.
*
* @param path File name (used for error reporting).
* @param content If the file would be a real file, this should be
* the content of the file.
*/
void addFile(const std::string &path, const std::string &content);
/**
* @brief Remove all files added with addFile() and parseFromArgs().
*/
void clearFiles();
/** /**
* @brief Returns current version number as a string. * @brief Returns current version number as a string.
* @return version, e.g. "1.38" * @return version, e.g. "1.38"
*/ */
static const char * version(); static const char * version();
const std::vector<std::string> &filenames() const;
virtual void reportStatus(unsigned int index, unsigned int max); virtual void reportStatus(unsigned int index, unsigned int max);
/** /**
@ -124,6 +121,10 @@ public:
void analyseFile(std::istream &f, const std::string &filename); void analyseFile(std::istream &f, const std::string &filename);
private: private:
/** @brief Process one file. */
unsigned int processFile();
/** @brief Check file */ /** @brief Check file */
void checkFile(const std::string &code, const char FileName[]); void checkFile(const std::string &code, const char FileName[]);
@ -148,13 +149,11 @@ private:
std::ostringstream _errout; std::ostringstream _errout;
Settings _settings; Settings _settings;
bool _useGlobalSuppressions; bool _useGlobalSuppressions;
std::vector<std::string> _filenames; std::string _filename;
std::string _fileContent;
void reportProgress(const std::string &filename, const char stage[], const unsigned int value); void reportProgress(const std::string &filename, const char stage[], const unsigned int value);
/** @brief Key is file name, and value is the content of the file */
std::map<std::string, std::string> _fileContents;
CheckUnusedFunctions _checkUnusedFunctions; CheckUnusedFunctions _checkUnusedFunctions;
ErrorLogger &_errorLogger; ErrorLogger &_errorLogger;

View File

@ -55,8 +55,7 @@ private:
CppCheck cppCheck(*this, true); CppCheck cppCheck(*this, true);
cppCheck.settings(settings); cppCheck.settings(settings);
cppCheck.addFile("test.cpp", code); cppCheck.check("test.cpp", code);
cppCheck.check();
reportUnmatchedSuppressions(cppCheck.settings().nomsg.getUnmatchedGlobalSuppressions()); reportUnmatchedSuppressions(cppCheck.settings().nomsg.getUnmatchedGlobalSuppressions());
} }
@ -105,8 +104,7 @@ private:
CppCheck cppCheck(*this, true); CppCheck cppCheck(*this, true);
cppCheck.settings(settings); cppCheck.settings(settings);
for (int i = 0; names[i] != NULL; ++i) for (int i = 0; names[i] != NULL; ++i)
cppCheck.addFile(names[i], codes[i]); cppCheck.check(names[i], codes[i]);
cppCheck.check();
reportUnmatchedSuppressions(cppCheck.settings().nomsg.getUnmatchedGlobalSuppressions()); reportUnmatchedSuppressions(cppCheck.settings().nomsg.getUnmatchedGlobalSuppressions());
} }