Cppcheck build dir: Better handling when --project is used

This commit is contained in:
Daniel Marjamäki 2016-12-08 22:46:44 +01:00
parent 30bee06cd2
commit e9d950d4f5
6 changed files with 72 additions and 24 deletions

View File

@ -17,6 +17,7 @@
*/ */
#include "cppcheckexecutor.h" #include "cppcheckexecutor.h"
#include "analyzerinfo.h"
#include "cmdlineparser.h" #include "cmdlineparser.h"
#include "cppcheck.h" #include "cppcheck.h"
#include "filelister.h" #include "filelister.h"
@ -803,11 +804,10 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck, int /*argc*/, const cha
} }
if (!settings.buildDir.empty()) { if (!settings.buildDir.empty()) {
const std::string filename(settings.buildDir + "/files.txt"); std::list<std::string> fileNames;
std::ofstream fout(filename.c_str()); for (std::map<std::string, std::size_t>::const_iterator i = _files.begin(); i != _files.end(); ++i)
for (std::map<std::string, std::size_t>::const_iterator f = _files.begin(); f != _files.end(); ++f) { fileNames.push_back(i->first);
fout << f->first << '\n'; AnalyzerInformation::writeFilesTxt(settings.buildDir, fileNames, settings.project.fileSettings);
}
} }
unsigned int returnValue = 0; unsigned int returnValue = 0;

View File

@ -26,6 +26,39 @@ AnalyzerInformation::~AnalyzerInformation()
close(); close();
} }
static std::string getFilename(const std::string &fullpath) {
std::string afile(fullpath);
std::string::size_type pos1 = fullpath.find_last_of("/\\");
pos1 = (pos1 == std::string::npos) ? 0U : (pos1 + 1U);
std::string::size_type pos2 = fullpath.rfind('.');
if (pos2 < pos1)
pos2 = std::string::npos;
if (pos2 != std::string::npos)
pos2 = pos2 - pos1;
return fullpath.substr(pos1,pos2);
}
void AnalyzerInformation::writeFilesTxt(const std::string &buildDir, const std::list<std::string> &sourcefiles, const std::list<ImportProject::FileSettings> &fileSettings)
{
std::map<std::string, unsigned int> fileCount;
const std::string filesTxt(buildDir + "/files.txt");
std::ofstream fout(filesTxt.c_str());
for (std::list<std::string>::const_iterator f = sourcefiles.begin(); f != sourcefiles.end(); ++f) {
const std::string afile = getFilename(*f);
if (fileCount.find(afile) == fileCount.end())
fileCount[afile] = 0;
fout << afile << ".a" << (++fileCount[afile]) << "::" << Path::fromNativeSeparators(*f) << '\n';
}
for (std::list<ImportProject::FileSettings>::const_iterator fs = fileSettings.begin(); fs != fileSettings.end(); ++fs) {
const std::string afile = getFilename(fs->filename);
if (fileCount.find(afile) == fileCount.end())
fileCount[afile] = 0;
fout << afile << ".a" << (++fileCount[afile]) << ":" << fs->cfg << ":" << Path::fromNativeSeparators(fs->filename) << std::endl;
}
}
void AnalyzerInformation::close() void AnalyzerInformation::close()
{ {
analyzerInfoFile.clear(); analyzerInfoFile.clear();
@ -58,20 +91,21 @@ static bool skipAnalysis(const std::string &analyzerInfoFile, unsigned long long
return true; return true;
} }
std::string AnalyzerInformation::getAnalyzerInfoFile(const std::string &buildDir, const std::string &sourcefile) std::string AnalyzerInformation::getAnalyzerInfoFile(const std::string &buildDir, const std::string &sourcefile, const std::string &cfg)
{ {
const std::string files(buildDir + "/files.txt"); const std::string files(buildDir + "/files.txt");
std::ifstream fin(files.c_str()); std::ifstream fin(files.c_str());
if (fin.is_open()) { if (fin.is_open()) {
int id = 1;
std::string line; std::string line;
const std::string endsWith(':' + cfg + ':' + sourcefile);
while (std::getline(fin,line)) { while (std::getline(fin,line)) {
if (line == sourcefile) { if (line.size() <= endsWith.size() + 2U)
std::ostringstream ostr; continue;
ostr << buildDir << '/' << id << ".analyzeinfo"; if (line.compare(line.size()-endsWith.size(), endsWith.size(), endsWith) != 0)
return ostr.str(); continue;
} std::ostringstream ostr;
id++; ostr << buildDir << '/' << line.substr(0,line.find(':'));
return ostr.str();
} }
} }
@ -87,13 +121,13 @@ std::string AnalyzerInformation::getAnalyzerInfoFile(const std::string &buildDir
return filename; return filename;
} }
bool AnalyzerInformation::analyzeFile(const std::string &buildDir, const std::string &sourcefile, unsigned long long checksum, std::list<ErrorLogger::ErrorMessage> *errors) bool AnalyzerInformation::analyzeFile(const std::string &buildDir, const std::string &sourcefile, const std::string &cfg, unsigned long long checksum, std::list<ErrorLogger::ErrorMessage> *errors)
{ {
if (buildDir.empty() || sourcefile.empty()) if (buildDir.empty() || sourcefile.empty())
return true; return true;
close(); close();
analyzerInfoFile = AnalyzerInformation::getAnalyzerInfoFile(buildDir,sourcefile); analyzerInfoFile = AnalyzerInformation::getAnalyzerInfoFile(buildDir,sourcefile,cfg);
if (skipAnalysis(analyzerInfoFile, checksum, errors)) if (skipAnalysis(analyzerInfoFile, checksum, errors))
return false; return false;

View File

@ -23,6 +23,8 @@
#include "config.h" #include "config.h"
#include "errorlogger.h" #include "errorlogger.h"
#include "importproject.h"
#include <list>
#include <string> #include <string>
#include <fstream> #include <fstream>
@ -47,12 +49,14 @@ class CPPCHECKLIB AnalyzerInformation {
public: public:
~AnalyzerInformation(); ~AnalyzerInformation();
static void writeFilesTxt(const std::string &buildDir, const std::list<std::string> &sourcefiles, const std::list<ImportProject::FileSettings> &fileSettings);
/** Close current TU.analyzerinfo file */ /** Close current TU.analyzerinfo file */
void close(); void close();
bool analyzeFile(const std::string &buildDir, const std::string &sourcefile, unsigned long long checksum, std::list<ErrorLogger::ErrorMessage> *errors); bool analyzeFile(const std::string &buildDir, const std::string &sourcefile, const std::string &cfg, unsigned long long checksum, std::list<ErrorLogger::ErrorMessage> *errors);
void reportErr(const ErrorLogger::ErrorMessage &msg, bool verbose); void reportErr(const ErrorLogger::ErrorMessage &msg, bool verbose);
void setFileInfo(const std::string &check, const std::string &fileInfo); void setFileInfo(const std::string &check, const std::string &fileInfo);
static std::string getAnalyzerInfoFile(const std::string &buildDir, const std::string &sourcefile); static std::string getAnalyzerInfoFile(const std::string &buildDir, const std::string &sourcefile, const std::string &cfg);
private: private:
std::ofstream fout; std::ofstream fout;
std::string analyzerInfoFile; std::string analyzerInfoFile;

View File

@ -312,14 +312,23 @@ namespace {
}; };
} }
void CheckUnusedFunctions::analyseWholeProgram(ErrorLogger * const errorLogger, const std::string &buildDir, const std::map<std::string, std::size_t> &files) void CheckUnusedFunctions::analyseWholeProgram(ErrorLogger * const errorLogger, const std::string &buildDir)
{ {
std::map<std::string, Location> decls; std::map<std::string, Location> decls;
std::set<std::string> calls; std::set<std::string> calls;
for (std::map<std::string, std::size_t>::const_iterator it = files.begin(); it != files.end(); ++it) { const std::string filesTxt(buildDir + "/files.txt");
const std::string &sourcefile = it->first; std::ifstream fin(filesTxt.c_str());
const std::string xmlfile = AnalyzerInformation::getAnalyzerInfoFile(buildDir, sourcefile); std::string filesTxtLine;
while (std::getline(fin, filesTxtLine)) {
const std::string::size_type firstColon = filesTxtLine.find(':');
if (firstColon == std::string::npos)
continue;
const std::string::size_type lastColon = filesTxtLine.rfind(':');
if (firstColon == lastColon)
continue;
const std::string xmlfile = filesTxtLine.substr(0,firstColon);
const std::string sourcefile = filesTxtLine.substr(lastColon+1);
tinyxml2::XMLDocument doc; tinyxml2::XMLDocument doc;
tinyxml2::XMLError error = doc.LoadFile(xmlfile.c_str()); tinyxml2::XMLError error = doc.LoadFile(xmlfile.c_str());

View File

@ -62,7 +62,7 @@ public:
std::string analyzerInfo() const; std::string analyzerInfo() const;
/** @brief Combine and analyze all analyzerInfos for all TUs */ /** @brief Combine and analyze all analyzerInfos for all TUs */
static void analyseWholeProgram(ErrorLogger * const errorLogger, const std::string &buildDir, const std::map<std::string, std::size_t> &files); static void analyseWholeProgram(ErrorLogger * const errorLogger, const std::string &buildDir);
private: private:

View File

@ -153,7 +153,7 @@ unsigned int CppCheck::processFile(const std::string& filename, const std::strin
// Calculate checksum so it can be compared with old checksum / future checksums // Calculate checksum so it can be compared with old checksum / future checksums
const unsigned int checksum = preprocessor.calculateChecksum(tokens1, toolinfo); const unsigned int checksum = preprocessor.calculateChecksum(tokens1, toolinfo);
std::list<ErrorLogger::ErrorMessage> errors; std::list<ErrorLogger::ErrorMessage> errors;
if (!analyzerInformation.analyzeFile(_settings.buildDir, filename, checksum, &errors)) { if (!analyzerInformation.analyzeFile(_settings.buildDir, filename, cfgname, checksum, &errors)) {
while (!errors.empty()) { while (!errors.empty()) {
reportErr(errors.front()); reportErr(errors.front());
errors.pop_front(); errors.pop_front();
@ -737,10 +737,11 @@ void CppCheck::analyseWholeProgram()
void CppCheck::analyseWholeProgram(const std::string &buildDir, const std::map<std::string, std::size_t> &files) void CppCheck::analyseWholeProgram(const std::string &buildDir, const std::map<std::string, std::size_t> &files)
{ {
(void)files;
if (buildDir.empty()) if (buildDir.empty())
return; return;
if (_settings.isEnabled("unusedFunction")) if (_settings.isEnabled("unusedFunction"))
CheckUnusedFunctions::analyseWholeProgram(this, buildDir, files); CheckUnusedFunctions::analyseWholeProgram(this, buildDir);
} }
bool CppCheck::isUnusedFunctionCheckEnabled() const bool CppCheck::isUnusedFunctionCheckEnabled() const