Cppcheck build dir: Better handling when --project is used
This commit is contained in:
parent
30bee06cd2
commit
e9d950d4f5
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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:
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue