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;
for (iter = filenames.begin(); iter != filenames.end(); ++iter)
cppcheck->addFile(*iter);
_filenames.push_back(*iter);
return true;
}
@ -146,7 +146,11 @@ int CppCheckExecutor::check(int argc, const char* const argv[])
if (_settings._jobs == 1)
{
// 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())
{
@ -155,9 +159,8 @@ int CppCheckExecutor::check(int argc, const char* const argv[])
else
{
// Multiple processes
const std::vector<std::string> &filenames = cppCheck.filenames();
Settings &settings = cppCheck.settings();
ThreadExecutor executor(filenames, settings, *this);
ThreadExecutor executor(_filenames, settings, *this);
returnValue = executor.check();
}

View File

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

View File

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

View File

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

View File

@ -54,155 +54,138 @@ void CppCheck::settings(const 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()
{
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;
std::sort(_filenames.begin(), _filenames.end());
// TODO: Should this be moved out to its own function so all the files can be
// analysed before any files are checked?
if (_settings.test_2_pass && _settings._jobs == 1)
{
for (unsigned int c = 0; c < _filenames.size(); c++)
{
const std::string fname = _filenames[c];
if (_settings.terminated())
break;
const std::string printname = Path::toNativeSeparators(_filename);
reportOut("Analysing " + printname + "...");
std::string fixedname = Path::toNativeSeparators(fname);
reportOut("Analysing " + fixedname + "..");
std::ifstream f(fname.c_str());
analyseFile(f, fname);
}
std::ifstream f(_filename.c_str());
analyseFile(f, _filename);
}
for (unsigned int c = 0; c < _filenames.size(); c++)
_errout.str("");
if (_settings.terminated())
return exitcode;
if (_settings._errorsOnly == false)
{
_errout.str("");
const std::string fname = _filenames[c];
if (_settings.terminated())
break;
if (_settings._errorsOnly == false)
{
std::string fixedpath(fname);
fixedpath = Path::simplifyPath(fixedpath.c_str());
fixedpath = Path::toNativeSeparators(fixedpath);
_errorLogger.reportOut(std::string("Checking ") + fixedpath + std::string("..."));
}
try
{
Preprocessor preprocessor(&_settings, this);
std::list<std::string> configurations;
std::string filedata = "";
if ((!_fileContents.empty()) && (_fileContents.find(_filenames[c]) != _fileContents.end()))
{
// File content was given as a string
std::istringstream iss(_fileContents[ _filenames[c] ]);
preprocessor.preprocess(iss, filedata, configurations, fname, _settings._includePaths);
}
else
{
// Only file name was given, read the content from file
std::ifstream fin(fname.c_str());
Timer t("Preprocessor::preprocess", _settings._showtime, &S_timerResults);
preprocessor.preprocess(fin, filedata, configurations, fname, _settings._includePaths);
}
_settings.ifcfg = bool(configurations.size() > 1);
if (!_settings.userDefines.empty())
{
configurations.clear();
configurations.push_back(_settings.userDefines);
}
int checkCount = 0;
for (std::list<std::string>::const_iterator it = configurations.begin(); it != configurations.end(); ++it)
{
// Check only 12 first configurations, after that bail out, unless --force
// was used.
if (!_settings._force && checkCount > 11)
{
const std::string fixedpath = Path::toNativeSeparators(fname);
ErrorLogger::ErrorMessage::FileLocation location;
location.setfile(fixedpath);
std::list<ErrorLogger::ErrorMessage::FileLocation> loclist;
loclist.push_back(location);
const std::string msg("Interrupted checking because of too many #ifdef configurations.\n"
"The checking of the file was interrupted because there were too many "
"#ifdef configurations. Checking of all #ifdef configurations can be forced "
"by --force command line option or from GUI preferences. However that may "
"increase the checking time.");
ErrorLogger::ErrorMessage errmsg(loclist,
Severity::information,
msg,
"toomanyconfigs",
false);
_errorLogger.reportErr(errmsg);
break;
}
cfg = *it;
Timer t("Preprocessor::getcode", _settings._showtime, &S_timerResults);
const std::string codeWithoutCfg = Preprocessor::getcode(filedata, *it, fname, &_settings, &_errorLogger);
t.Stop();
// If only errors are printed, print filename after the check
if (_settings._errorsOnly == false && it != configurations.begin())
{
std::string fixedpath = Path::simplifyPath(fname.c_str());
fixedpath = Path::toNativeSeparators(fixedpath);
_errorLogger.reportOut(std::string("Checking ") + fixedpath + ": " + cfg + std::string("..."));
}
std::string appendCode = _settings.append();
if (!appendCode.empty())
Preprocessor::preprocessWhitespaces(appendCode);
checkFile(codeWithoutCfg + appendCode, _filenames[c].c_str());
++checkCount;
}
}
catch (std::runtime_error &e)
{
// Exception was thrown when checking this file..
const std::string fixedpath = Path::toNativeSeparators(fname);
_errorLogger.reportOut("Bailing out from checking " + fixedpath + ": " + e.what());
}
reportUnmatchedSuppressions(_settings.nomsg.getUnmatchedLocalSuppressions(fname));
_errorLogger.reportStatus(c + 1, (unsigned int)_filenames.size());
std::string fixedpath(_filename);
fixedpath = Path::simplifyPath(fixedpath.c_str());
fixedpath = Path::toNativeSeparators(fixedpath);
_errorLogger.reportOut(std::string("Checking ") + fixedpath + std::string("..."));
}
try
{
Preprocessor preprocessor(&_settings, this);
std::list<std::string> configurations;
std::string filedata = "";
if (!_fileContent.empty())
{
// File content was given as a string
std::istringstream iss(_fileContent);
preprocessor.preprocess(iss, filedata, configurations, _filename, _settings._includePaths);
}
else
{
// Only file name was given, read the content from file
std::ifstream fin(_filename.c_str());
Timer t("Preprocessor::preprocess", _settings._showtime, &S_timerResults);
preprocessor.preprocess(fin, filedata, configurations, _filename, _settings._includePaths);
}
_settings.ifcfg = bool(configurations.size() > 1);
if (!_settings.userDefines.empty())
{
configurations.clear();
configurations.push_back(_settings.userDefines);
}
int checkCount = 0;
for (std::list<std::string>::const_iterator it = configurations.begin(); it != configurations.end(); ++it)
{
// Check only 12 first configurations, after that bail out, unless --force
// was used.
if (!_settings._force && checkCount > 11)
{
const std::string fixedpath = Path::toNativeSeparators(_filename);
ErrorLogger::ErrorMessage::FileLocation location;
location.setfile(fixedpath);
std::list<ErrorLogger::ErrorMessage::FileLocation> loclist;
loclist.push_back(location);
const std::string msg("Interrupted checking because of too many #ifdef configurations.\n"
"The checking of the file was interrupted because there were too many "
"#ifdef configurations. Checking of all #ifdef configurations can be forced "
"by --force command line option or from GUI preferences. However that may "
"increase the checking time.");
ErrorLogger::ErrorMessage errmsg(loclist,
Severity::information,
msg,
"toomanyconfigs",
false);
_errorLogger.reportErr(errmsg);
break;
}
cfg = *it;
Timer t("Preprocessor::getcode", _settings._showtime, &S_timerResults);
const std::string codeWithoutCfg = Preprocessor::getcode(filedata, *it, _filename, &_settings, &_errorLogger);
t.Stop();
// If only errors are printed, print filename after the check
if (_settings._errorsOnly == false && it != configurations.begin())
{
std::string fixedpath = Path::simplifyPath(_filename.c_str());
fixedpath = Path::toNativeSeparators(fixedpath);
_errorLogger.reportOut(std::string("Checking ") + fixedpath + ": " + cfg + std::string("..."));
}
std::string appendCode = _settings.append();
if (!appendCode.empty())
Preprocessor::preprocessWhitespaces(appendCode);
checkFile(codeWithoutCfg + appendCode, _filename.c_str());
++checkCount;
}
}
catch (std::runtime_error &e)
{
// Exception was thrown when checking this file..
const std::string fixedpath = Path::toNativeSeparators(_filename);
_errorLogger.reportOut("Bailing out from checking " + fixedpath + ": " + e.what());
}
reportUnmatchedSuppressions(_settings.nomsg.getUnmatchedLocalSuppressions(_filename));
// This generates false positives - especially for libraries
const bool verbose_orig = _settings._verbose;
_settings._verbose = false;
@ -445,11 +428,6 @@ void CppCheck::reportOut(const std::string &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)
{
_errorLogger.reportProgress(filename, stage, value);

View File

@ -55,7 +55,29 @@ public:
* parseFromArgs() or settings() and addFile() before calling this.
* @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
@ -71,37 +93,12 @@ public:
*/
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.
* @return version, e.g. "1.38"
*/
static const char * version();
const std::vector<std::string> &filenames() const;
virtual void reportStatus(unsigned int index, unsigned int max);
/**
@ -124,6 +121,10 @@ public:
void analyseFile(std::istream &f, const std::string &filename);
private:
/** @brief Process one file. */
unsigned int processFile();
/** @brief Check file */
void checkFile(const std::string &code, const char FileName[]);
@ -148,13 +149,11 @@ private:
std::ostringstream _errout;
Settings _settings;
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);
/** @brief Key is file name, and value is the content of the file */
std::map<std::string, std::string> _fileContents;
CheckUnusedFunctions _checkUnusedFunctions;
ErrorLogger &_errorLogger;

View File

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