greatly improved error handling in Cppcheck project file parsing / some cleanups (#4752)
This commit is contained in:
parent
0dddba3bd6
commit
14e78e1800
|
@ -603,25 +603,10 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[])
|
|||
else if (std::strncmp(argv[i], "--platform=", 11) == 0) {
|
||||
const std::string platform(11+argv[i]);
|
||||
|
||||
if (platform == "win32A")
|
||||
mSettings->platform(Settings::Win32A);
|
||||
else if (platform == "win32W")
|
||||
mSettings->platform(Settings::Win32W);
|
||||
else if (platform == "win64")
|
||||
mSettings->platform(Settings::Win64);
|
||||
else if (platform == "unix32")
|
||||
mSettings->platform(Settings::Unix32);
|
||||
else if (platform == "unix64")
|
||||
mSettings->platform(Settings::Unix64);
|
||||
else if (platform == "native")
|
||||
mSettings->platform(Settings::Native);
|
||||
else if (platform == "unspecified")
|
||||
mSettings->platform(Settings::Unspecified);
|
||||
else if (!mSettings->loadPlatformFile(argv[0], platform, mSettings->verbose)) {
|
||||
std::string message("unrecognized platform: \"");
|
||||
message += platform;
|
||||
message += "\".";
|
||||
printError(message);
|
||||
std::string errstr;
|
||||
const std::vector<std::string> paths = {argv[0]};
|
||||
if (!mSettings->platform(platform, errstr, paths)) {
|
||||
printError(errstr);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -669,7 +654,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[])
|
|||
// --project
|
||||
else if (std::strncmp(argv[i], "--project=", 10) == 0) {
|
||||
mSettings->checkAllConfigurations = false; // Can be overridden with --max-configs or --force
|
||||
const std::string projectFile = argv[i]+10;
|
||||
std::string projectFile = argv[i]+10;
|
||||
ImportProject::Type projType = mSettings->project.import(projectFile, mSettings);
|
||||
mSettings->project.projectType = projType;
|
||||
if (projType == ImportProject::Type::CPPCHECK_GUI) {
|
||||
|
@ -680,32 +665,27 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[])
|
|||
const auto& excludedPaths = mSettings->project.guiProject.excludedPaths;
|
||||
std::copy(excludedPaths.cbegin(), excludedPaths.cend(), std::back_inserter(mIgnoredPaths));
|
||||
|
||||
const std::string platform(mSettings->project.guiProject.platform);
|
||||
std::string platform(mSettings->project.guiProject.platform);
|
||||
|
||||
if (platform == "win32A")
|
||||
mSettings->platform(Settings::Win32A);
|
||||
else if (platform == "win32W")
|
||||
mSettings->platform(Settings::Win32W);
|
||||
else if (platform == "win64")
|
||||
mSettings->platform(Settings::Win64);
|
||||
else if (platform == "unix32")
|
||||
mSettings->platform(Settings::Unix32);
|
||||
else if (platform == "unix64")
|
||||
mSettings->platform(Settings::Unix64);
|
||||
else if (platform == "native")
|
||||
mSettings->platform(Settings::Native);
|
||||
else if (platform == "unspecified" || platform == "Unspecified" || platform.empty())
|
||||
;
|
||||
else if (!mSettings->loadPlatformFile(projectFile.c_str(), platform, mSettings->verbose) && !mSettings->loadPlatformFile(argv[0], platform, mSettings->verbose)) {
|
||||
std::string message("unrecognized platform: \"");
|
||||
message += platform;
|
||||
message += "\".";
|
||||
printError(message);
|
||||
return false;
|
||||
// keep existing platform from command-line intact
|
||||
if (!platform.empty()) {
|
||||
if (platform == "Unspecified") {
|
||||
printMessage("'Unspecified' is a deprecated platform type and will be removed in Cppcheck 2.14. Please use 'unspecified' instead.");
|
||||
platform = "unspecified";
|
||||
}
|
||||
|
||||
std::string errstr;
|
||||
const std::vector<std::string> paths = {projectFile, argv[0]};
|
||||
if (!mSettings->platform(platform, errstr, paths)) {
|
||||
printError(errstr);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mSettings->project.guiProject.projectFile.empty())
|
||||
if (!mSettings->project.guiProject.projectFile.empty()) {
|
||||
projectFile = mSettings->project.guiProject.projectFile;
|
||||
projType = mSettings->project.import(mSettings->project.guiProject.projectFile, mSettings);
|
||||
}
|
||||
}
|
||||
if (projType == ImportProject::Type::VS_SLN || projType == ImportProject::Type::VS_VCXPROJ) {
|
||||
if (mSettings->project.guiProject.analyzeAllVsConfigs == "false")
|
||||
|
|
|
@ -257,11 +257,11 @@ MainWindow::MainWindow(TranslationHandler* th, QSettings* settings) :
|
|||
// For other platforms default to unspecified/default which means the
|
||||
// platform Cppcheck GUI was compiled on.
|
||||
#if defined(_WIN32)
|
||||
const Settings::PlatformType defaultPlatform = Settings::Win32W;
|
||||
const cppcheck::Platform::PlatformType defaultPlatform = cppcheck::Platform::Win32W;
|
||||
#else
|
||||
const Settings::PlatformType defaultPlatform = Settings::Unspecified;
|
||||
const cppcheck::Platform::PlatformType defaultPlatform = cppcheck::Platform::Unspecified;
|
||||
#endif
|
||||
Platform &platform = mPlatforms.get((Settings::PlatformType)mSettings->value(SETTINGS_CHECKED_PLATFORM, defaultPlatform).toInt());
|
||||
Platform &platform = mPlatforms.get((cppcheck::Platform::PlatformType)mSettings->value(SETTINGS_CHECKED_PLATFORM, defaultPlatform).toInt());
|
||||
platform.mActMainWindow->setChecked(true);
|
||||
|
||||
mNetworkAccessManager = new QNetworkAccessManager(this);
|
||||
|
@ -477,7 +477,7 @@ void MainWindow::doAnalyzeProject(ImportProject p, const bool checkLibrary, cons
|
|||
p.ignorePaths(v);
|
||||
|
||||
if (!mProjectFile->getAnalyzeAllVsConfigs()) {
|
||||
const Settings::PlatformType platform = (Settings::PlatformType) mSettings->value(SETTINGS_CHECKED_PLATFORM, 0).toInt();
|
||||
const cppcheck::Platform::PlatformType platform = (cppcheck::Platform::PlatformType) mSettings->value(SETTINGS_CHECKED_PLATFORM, 0).toInt();
|
||||
p.selectOneVsConfig(platform);
|
||||
}
|
||||
} else {
|
||||
|
@ -1908,7 +1908,7 @@ void MainWindow::selectPlatform()
|
|||
{
|
||||
QAction *action = qobject_cast<QAction *>(sender());
|
||||
if (action) {
|
||||
const Settings::PlatformType platform = (Settings::PlatformType) action->data().toInt();
|
||||
const cppcheck::Platform::PlatformType platform = (cppcheck::Platform::PlatformType) action->data().toInt();
|
||||
mSettings->setValue(SETTINGS_CHECKED_PLATFORM, platform);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ Platforms::Platforms(QObject *parent)
|
|||
init();
|
||||
}
|
||||
|
||||
void Platforms::add(const QString &title, Settings::PlatformType platform)
|
||||
void Platforms::add(const QString &title, cppcheck::Platform::PlatformType platform)
|
||||
{
|
||||
Platform plat;
|
||||
plat.mTitle = title;
|
||||
|
@ -35,12 +35,12 @@ void Platforms::add(const QString &title, Settings::PlatformType platform)
|
|||
|
||||
void Platforms::init()
|
||||
{
|
||||
add(tr("Native"), Settings::Native);
|
||||
add(tr("Unix 32-bit"), Settings::Unix32);
|
||||
add(tr("Unix 64-bit"), Settings::Unix64);
|
||||
add(tr("Windows 32-bit ANSI"), Settings::Win32A);
|
||||
add(tr("Windows 32-bit Unicode"), Settings::Win32W);
|
||||
add(tr("Windows 64-bit"), Settings::Win64);
|
||||
add(tr("Native"), cppcheck::Platform::Native);
|
||||
add(tr("Unix 32-bit"), cppcheck::Platform::Unix32);
|
||||
add(tr("Unix 64-bit"), cppcheck::Platform::Unix64);
|
||||
add(tr("Windows 32-bit ANSI"), cppcheck::Platform::Win32A);
|
||||
add(tr("Windows 32-bit Unicode"), cppcheck::Platform::Win32W);
|
||||
add(tr("Windows 64-bit"), cppcheck::Platform::Win64);
|
||||
}
|
||||
|
||||
int Platforms::getCount() const
|
||||
|
@ -48,7 +48,7 @@ int Platforms::getCount() const
|
|||
return mPlatforms.count();
|
||||
}
|
||||
|
||||
Platform& Platforms::get(Settings::PlatformType platform)
|
||||
Platform& Platforms::get(cppcheck::Platform::PlatformType platform)
|
||||
{
|
||||
QList<Platform>::iterator iter = mPlatforms.begin();
|
||||
while (iter != mPlatforms.end()) {
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#ifndef PLATFORMS_H
|
||||
#define PLATFORMS_H
|
||||
|
||||
#include "settings.h"
|
||||
#include "platform.h"
|
||||
|
||||
#include <QList>
|
||||
#include <QObject>
|
||||
|
@ -35,7 +35,7 @@ class QAction;
|
|||
*/
|
||||
struct Platform {
|
||||
QString mTitle; /**< Text visible in the GUI. */
|
||||
Settings::PlatformType mType; /**< Type in the core. */
|
||||
cppcheck::Platform::PlatformType mType; /**< Type in the core. */
|
||||
QAction *mActMainWindow; /**< Pointer to main window action item. */
|
||||
};
|
||||
|
||||
|
@ -47,10 +47,10 @@ class Platforms : public QObject {
|
|||
|
||||
public:
|
||||
explicit Platforms(QObject *parent = nullptr);
|
||||
void add(const QString &title, Settings::PlatformType platform);
|
||||
void add(const QString &title, cppcheck::Platform::PlatformType platform);
|
||||
int getCount() const;
|
||||
void init();
|
||||
Platform& get(Settings::PlatformType platform);
|
||||
Platform& get(cppcheck::Platform::PlatformType platform);
|
||||
|
||||
QList<Platform> mPlatforms;
|
||||
};
|
||||
|
|
|
@ -53,7 +53,6 @@ void ProjectFile::clear()
|
|||
mRootPath.clear();
|
||||
mBuildDir.clear();
|
||||
mImportProject.clear();
|
||||
mAnalyzeAllVsConfigs = true;
|
||||
mIncludeDirs.clear();
|
||||
mDefines.clear();
|
||||
mUndefines.clear();
|
||||
|
|
|
@ -57,7 +57,7 @@ static const struct CWE CWE190(190U); // Integer Overflow or Wraparound
|
|||
void CheckType::checkTooBigBitwiseShift()
|
||||
{
|
||||
// unknown sizeof(int) => can't run this checker
|
||||
if (mSettings->platformType == Settings::Unspecified)
|
||||
if (mSettings->platformType == cppcheck::Platform::Unspecified)
|
||||
return;
|
||||
|
||||
for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) {
|
||||
|
@ -160,7 +160,7 @@ void CheckType::tooBigSignedBitwiseShiftError(const Token *tok, int lhsbits, con
|
|||
void CheckType::checkIntegerOverflow()
|
||||
{
|
||||
// unknown sizeof(int) => can't run this checker
|
||||
if (mSettings->platformType == Settings::Unspecified || mSettings->int_bit >= MathLib::bigint_bits)
|
||||
if (mSettings->platformType == cppcheck::Platform::Unspecified || mSettings->int_bit >= MathLib::bigint_bits)
|
||||
return;
|
||||
|
||||
for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) {
|
||||
|
@ -436,7 +436,7 @@ void CheckType::checkFloatToIntegerOverflow(const Token *tok, const ValueType *v
|
|||
floatToIntegerOverflowError(tok, f);
|
||||
else if ((-f.floatValue) > std::exp2(mSettings->long_long_bit - 1))
|
||||
floatToIntegerOverflowError(tok, f);
|
||||
else if (mSettings->platformType != Settings::Unspecified) {
|
||||
else if (mSettings->platformType != cppcheck::Platform::Unspecified) {
|
||||
int bits = 0;
|
||||
if (vtint->type == ValueType::Type::CHAR)
|
||||
bits = mSettings->char_bit;
|
||||
|
|
|
@ -586,7 +586,7 @@ unsigned int CppCheck::check(const ImportProject::FileSettings &fs)
|
|||
temp.mSettings.standards.setCPP(fs.standard);
|
||||
else if (!fs.standard.empty())
|
||||
temp.mSettings.standards.setC(fs.standard);
|
||||
if (fs.platformType != Settings::Unspecified)
|
||||
if (fs.platformType != cppcheck::Platform::Unspecified)
|
||||
temp.mSettings.platform(fs.platformType);
|
||||
if (mSettings.clang) {
|
||||
temp.mSettings.includePaths.insert(temp.mSettings.includePaths.end(), fs.systemIncludePaths.cbegin(), fs.systemIncludePaths.cend());
|
||||
|
|
|
@ -1119,6 +1119,9 @@ static std::string istream_to_string(std::istream &istr)
|
|||
return std::string(std::istreambuf_iterator<char>(istr), eos);
|
||||
}
|
||||
|
||||
static const char * readSafe(const char *s, const char *def) {
|
||||
return s ? s : def;
|
||||
}
|
||||
|
||||
bool ImportProject::importCppcheckGuiProject(std::istream &istr, Settings *settings)
|
||||
{
|
||||
|
@ -1144,13 +1147,13 @@ bool ImportProject::importCppcheckGuiProject(std::istream &istr, Settings *setti
|
|||
guiProject.analyzeAllVsConfigs.clear();
|
||||
|
||||
for (const tinyxml2::XMLElement *node = rootnode->FirstChildElement(); node; node = node->NextSiblingElement()) {
|
||||
if (strcmp(node->Name(), CppcheckXml::RootPathName) == 0 && node->Attribute(CppcheckXml::RootPathNameAttrib)) {
|
||||
temp.basePaths.push_back(joinRelativePath(path, node->Attribute(CppcheckXml::RootPathNameAttrib)));
|
||||
temp.relativePaths = true;
|
||||
} else if (strcmp(node->Name(), CppcheckXml::BugHunting) == 0)
|
||||
;
|
||||
else if (strcmp(node->Name(), CppcheckXml::BuildDirElementName) == 0)
|
||||
temp.buildDir = joinRelativePath(path, node->GetText() ? node->GetText() : "");
|
||||
if (strcmp(node->Name(), CppcheckXml::RootPathName) == 0) {
|
||||
if (node->Attribute(CppcheckXml::RootPathNameAttrib)) {
|
||||
temp.basePaths.push_back(joinRelativePath(path, node->Attribute(CppcheckXml::RootPathNameAttrib)));
|
||||
temp.relativePaths = true;
|
||||
}
|
||||
} else if (strcmp(node->Name(), CppcheckXml::BuildDirElementName) == 0)
|
||||
temp.buildDir = joinRelativePath(path, readSafe(node->GetText(), ""));
|
||||
else if (strcmp(node->Name(), CppcheckXml::IncludeDirElementName) == 0)
|
||||
temp.includePaths = readXmlStringList(node, path, CppcheckXml::DirElementName, CppcheckXml::DirNameAttrib);
|
||||
else if (strcmp(node->Name(), CppcheckXml::DefinesElementName) == 0)
|
||||
|
@ -1158,8 +1161,11 @@ bool ImportProject::importCppcheckGuiProject(std::istream &istr, Settings *setti
|
|||
else if (strcmp(node->Name(), CppcheckXml::UndefinesElementName) == 0) {
|
||||
for (const std::string &u : readXmlStringList(node, "", CppcheckXml::UndefineName, nullptr))
|
||||
temp.userUndefs.insert(u);
|
||||
} else if (strcmp(node->Name(), CppcheckXml::ImportProjectElementName) == 0)
|
||||
guiProject.projectFile = path + (node->GetText() ? node->GetText() : "");
|
||||
} else if (strcmp(node->Name(), CppcheckXml::ImportProjectElementName) == 0) {
|
||||
const std::string t_str = readSafe(node->GetText(), "");
|
||||
if (!t_str.empty())
|
||||
guiProject.projectFile = path + t_str;
|
||||
}
|
||||
else if (strcmp(node->Name(), CppcheckXml::PathsElementName) == 0)
|
||||
paths = readXmlStringList(node, path, CppcheckXml::PathName, CppcheckXml::PathNameAttrib);
|
||||
else if (strcmp(node->Name(), CppcheckXml::ExcludeElementName) == 0)
|
||||
|
@ -1176,25 +1182,22 @@ bool ImportProject::importCppcheckGuiProject(std::istream &istr, Settings *setti
|
|||
for (const tinyxml2::XMLElement *child = node->FirstChildElement(); child; child = child->NextSiblingElement()) {
|
||||
if (strcmp(child->Name(), CppcheckXml::SuppressionElementName) != 0)
|
||||
continue;
|
||||
auto read = [](const char *s, const char *def) {
|
||||
return s ? s : def;
|
||||
};
|
||||
Suppressions::Suppression s;
|
||||
s.errorId = read(child->GetText(), "");
|
||||
s.fileName = read(child->Attribute("fileName"), "");
|
||||
s.errorId = readSafe(child->GetText(), "");
|
||||
s.fileName = readSafe(child->Attribute("fileName"), "");
|
||||
if (!s.fileName.empty())
|
||||
s.fileName = joinRelativePath(path, s.fileName);
|
||||
s.lineNumber = child->IntAttribute("lineNumber", Suppressions::Suppression::NO_LINE);
|
||||
s.symbolName = read(child->Attribute("symbolName"), "");
|
||||
std::istringstream(read(child->Attribute("hash"), "0")) >> s.hash;
|
||||
s.symbolName = readSafe(child->Attribute("symbolName"), "");
|
||||
std::istringstream(readSafe(child->Attribute("hash"), "0")) >> s.hash;
|
||||
suppressions.push_back(std::move(s));
|
||||
}
|
||||
} else if (strcmp(node->Name(), CppcheckXml::VSConfigurationElementName) == 0)
|
||||
guiProject.checkVsConfigs = readXmlStringList(node, emptyString, CppcheckXml::VSConfigurationName, nullptr);
|
||||
else if (strcmp(node->Name(), CppcheckXml::PlatformElementName) == 0)
|
||||
guiProject.platform = node->GetText();
|
||||
guiProject.platform = readSafe(node->GetText(), "");
|
||||
else if (strcmp(node->Name(), CppcheckXml::AnalyzeAllVsConfigsElementName) == 0)
|
||||
guiProject.analyzeAllVsConfigs = node->GetText();
|
||||
guiProject.analyzeAllVsConfigs = readSafe(node->GetText(), "");
|
||||
else if (strcmp(node->Name(), CppcheckXml::Parser) == 0)
|
||||
temp.clang = true;
|
||||
else if (strcmp(node->Name(), CppcheckXml::AddonsElementName) == 0) {
|
||||
|
@ -1210,13 +1213,13 @@ bool ImportProject::importCppcheckGuiProject(std::istream &istr, Settings *setti
|
|||
temp.clangTidy = true;
|
||||
}
|
||||
} else if (strcmp(node->Name(), CppcheckXml::CheckHeadersElementName) == 0)
|
||||
temp.checkHeaders = (strcmp(node->GetText(), "true") == 0);
|
||||
temp.checkHeaders = (strcmp(readSafe(node->GetText(), ""), "true") == 0);
|
||||
else if (strcmp(node->Name(), CppcheckXml::CheckUnusedTemplatesElementName) == 0)
|
||||
temp.checkUnusedTemplates = (strcmp(node->GetText(), "true") == 0);
|
||||
temp.checkUnusedTemplates = (strcmp(readSafe(node->GetText(), ""), "true") == 0);
|
||||
else if (strcmp(node->Name(), CppcheckXml::MaxCtuDepthElementName) == 0)
|
||||
temp.maxCtuDepth = std::atoi(node->GetText());
|
||||
temp.maxCtuDepth = std::atoi(readSafe(node->GetText(), "")); // TODO: get rid of atoi()
|
||||
else if (strcmp(node->Name(), CppcheckXml::MaxTemplateRecursionElementName) == 0)
|
||||
temp.maxTemplateRecursion = std::atoi(node->GetText());
|
||||
temp.maxTemplateRecursion = std::atoi(readSafe(node->GetText(), "")); // TODO: get rid of atoi()
|
||||
else if (strcmp(node->Name(), CppcheckXml::CheckUnknownFunctionReturn) == 0)
|
||||
; // TODO
|
||||
else if (strcmp(node->Name(), Settings::SafeChecks::XmlRootName) == 0) {
|
||||
|
@ -1229,8 +1232,10 @@ bool ImportProject::importCppcheckGuiProject(std::istream &istr, Settings *setti
|
|||
temp.safeChecks.internalFunctions = true;
|
||||
else if (strcmp(child->Name(), Settings::SafeChecks::XmlExternalVariables) == 0)
|
||||
temp.safeChecks.externalVariables = true;
|
||||
else
|
||||
else {
|
||||
printError("Unknown '" + std::string(Settings::SafeChecks::XmlRootName) + "' element '" + std::string(child->Name()) + "' in Cppcheck project file");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else if (strcmp(node->Name(), CppcheckXml::TagWarningsElementName) == 0)
|
||||
; // TODO
|
||||
|
@ -1238,15 +1243,17 @@ bool ImportProject::importCppcheckGuiProject(std::istream &istr, Settings *setti
|
|||
else if (strcmp(node->Name(), CppcheckXml::BughuntingElementName) == 0)
|
||||
temp.premiumArgs += " --bughunting";
|
||||
else if (strcmp(node->Name(), CppcheckXml::CertIntPrecisionElementName) == 0)
|
||||
temp.premiumArgs += std::string(" --cert-c-int-precision=") + (node->GetText() ? node->GetText() : "0");
|
||||
temp.premiumArgs += std::string(" --cert-c-int-precision=") + readSafe(node->GetText(), "0");
|
||||
else if (strcmp(node->Name(), CppcheckXml::CodingStandardsElementName) == 0) {
|
||||
for (const tinyxml2::XMLElement *child = node->FirstChildElement(); child; child = child->NextSiblingElement()) {
|
||||
if (strcmp(child->Name(), CppcheckXml::CodingStandardElementName) == 0 && child->GetText())
|
||||
temp.premiumArgs += std::string(" --") + child->GetText();
|
||||
}
|
||||
}
|
||||
else
|
||||
else {
|
||||
printError("Unknown element '" + std::string(node->Name()) + "' in Cppcheck project file");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
settings->basePaths = temp.basePaths;
|
||||
settings->relativePaths |= temp.relativePaths;
|
||||
|
@ -1276,7 +1283,7 @@ bool ImportProject::importCppcheckGuiProject(std::istream &istr, Settings *setti
|
|||
return true;
|
||||
}
|
||||
|
||||
void ImportProject::selectOneVsConfig(Settings::PlatformType platform)
|
||||
void ImportProject::selectOneVsConfig(cppcheck::Platform::PlatformType platform)
|
||||
{
|
||||
std::set<std::string> filenames;
|
||||
for (std::list<ImportProject::FileSettings>::iterator it = fileSettings.begin(); it != fileSettings.end();) {
|
||||
|
@ -1288,11 +1295,11 @@ void ImportProject::selectOneVsConfig(Settings::PlatformType platform)
|
|||
bool remove = false;
|
||||
if (fs.cfg.compare(0,5,"Debug") != 0)
|
||||
remove = true;
|
||||
if (platform == Settings::Win64 && fs.platformType != platform)
|
||||
if (platform == cppcheck::Platform::Win64 && fs.platformType != platform)
|
||||
remove = true;
|
||||
else if ((platform == Settings::Win32A || platform == Settings::Win32W) && fs.platformType == Settings::Win64)
|
||||
else if ((platform == cppcheck::Platform::Win32A || platform == cppcheck::Platform::Win32W) && fs.platformType == cppcheck::Platform::Win64)
|
||||
remove = true;
|
||||
else if (fs.platformType != Settings::Win64 && platform == Settings::Win64)
|
||||
else if (fs.platformType != cppcheck::Platform::Win64 && platform == cppcheck::Platform::Win64)
|
||||
remove = true;
|
||||
else if (filenames.find(fs.filename) != filenames.end())
|
||||
remove = true;
|
||||
|
|
|
@ -133,7 +133,6 @@ namespace CppcheckXml {
|
|||
const char ImportProjectElementName[] = "importproject";
|
||||
const char AnalyzeAllVsConfigsElementName[] = "analyze-all-vs-configs";
|
||||
const char Parser[] = "parser";
|
||||
const char BugHunting[] = "bug-hunting";
|
||||
const char IncludeDirElementName[] = "includedir";
|
||||
const char DirElementName[] = "dir";
|
||||
const char DirNameAttrib[] = "name";
|
||||
|
|
|
@ -157,6 +157,45 @@ bool cppcheck::Platform::platform(cppcheck::Platform::PlatformType type)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool cppcheck::Platform::platform(const std::string& platformstr, std::string& errstr, const std::vector<std::string>& paths, bool verbose)
|
||||
{
|
||||
if (platformstr == "win32A")
|
||||
platform(Win32A);
|
||||
else if (platformstr == "win32W")
|
||||
platform(Win32W);
|
||||
else if (platformstr == "win64")
|
||||
platform(Win64);
|
||||
else if (platformstr == "unix32")
|
||||
platform(Unix32);
|
||||
else if (platformstr == "unix64")
|
||||
platform(Unix64);
|
||||
else if (platformstr == "native")
|
||||
platform(Native);
|
||||
else if (platformstr == "unspecified")
|
||||
platform(Unspecified);
|
||||
else if (paths.empty()) {
|
||||
errstr = "unrecognized platform: '" + platformstr + "' (no lookup).";
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
bool found = false;
|
||||
for (const std::string& path : paths) {
|
||||
if (verbose)
|
||||
std::cout << "looking for platform '" + platformstr + "' in '" + path + "'" << std::endl;
|
||||
if (loadPlatformFile(path.c_str(), platformstr, verbose)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
errstr = "unrecognized platform: '" + platformstr + "'.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cppcheck::Platform::loadPlatformFile(const char exename[], const std::string &filename, bool verbose)
|
||||
{
|
||||
// TODO: only append .xml if missing
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include <climits>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/// @addtogroup Core
|
||||
/// @{
|
||||
|
@ -113,9 +114,12 @@ namespace cppcheck {
|
|||
/** platform type */
|
||||
PlatformType platformType;
|
||||
|
||||
/** set the platform type for predefined platforms */
|
||||
/** set the platform type for predefined platforms - deprecated use platform(const std::string&) instead */
|
||||
bool platform(PlatformType type);
|
||||
|
||||
/** set the platform type */
|
||||
bool platform(const std::string& platformstr, std::string& errstr, const std::vector<std::string>& paths = {}, bool verbose = false);
|
||||
|
||||
/**
|
||||
* load platform file
|
||||
* @param exename application path
|
||||
|
|
|
@ -9049,7 +9049,7 @@ void Tokenizer::simplifyMicrosoftStringFunctions()
|
|||
if (!mSettings->isWindowsPlatform())
|
||||
return;
|
||||
|
||||
const bool ansi = mSettings->platformType == Settings::Win32A;
|
||||
const bool ansi = mSettings->platformType == cppcheck::Platform::Win32A;
|
||||
for (Token *tok = list.front(); tok; tok = tok->next()) {
|
||||
if (tok->strAt(1) != "(")
|
||||
continue;
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
release notes for cppcheck-2.11
|
||||
|
||||
- The platform type 'Unspecified' within .cppcheck projects has been deprecated and will be removed in Cppcheck 2.14. Please use 'unspecified' instead.
|
|
@ -39,22 +39,34 @@ def test_project_force_U(tmpdir):
|
|||
assert stderr == '[bug1.cpp:2]: (error) Division by zero.\n'
|
||||
|
||||
|
||||
def __write_cppcheck_project_file(tmpdir, platform=None, importproject=None):
|
||||
project_file = os.path.join(tmpdir, 'Project.cppcheck')
|
||||
|
||||
if platform is not None:
|
||||
platform = '<platform>{}</platform>'.format(platform)
|
||||
if importproject is not None:
|
||||
platform = '<importproject>{}</importproject>'.format(importproject)
|
||||
|
||||
with open(project_file, 'wt') as f:
|
||||
f.write(
|
||||
"""<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="1">
|
||||
{}
|
||||
{}
|
||||
<paths>
|
||||
<dir name="."/>
|
||||
</paths>
|
||||
</project>""".format(platform, importproject)
|
||||
)
|
||||
|
||||
return project_file
|
||||
|
||||
|
||||
def test_project_custom_platform(tmpdir):
|
||||
"""
|
||||
import cppcheck project that contains a custom platform file
|
||||
"""
|
||||
project_file = os.path.join(tmpdir, 'Project.cppcheck')
|
||||
|
||||
with open(project_file, 'wt') as f:
|
||||
f.write("""
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="1">
|
||||
<platform>p1.xml</platform>
|
||||
<paths>
|
||||
<dir name="."/>
|
||||
</paths>
|
||||
</project>
|
||||
""")
|
||||
project_file = __write_cppcheck_project_file(tmpdir, platform='p1.xml')
|
||||
|
||||
with open(os.path.join(tmpdir, 'p1.xml'), 'wt') as f:
|
||||
f.write('<?xml version="1.0"?>\n<platform/>')
|
||||
|
@ -62,6 +74,154 @@ def test_project_custom_platform(tmpdir):
|
|||
with open(os.path.join(tmpdir, '1.c'), 'wt') as f:
|
||||
f.write("int x;")
|
||||
|
||||
ret, stdout, stderr = cppcheck(['--project=' + project_file, '--template=cppcheck1'])
|
||||
ret, stdout, stderr = cppcheck(['--platform=native', '--project=' + project_file, '--template=cppcheck1', '-q'])
|
||||
assert ret == 0, stdout
|
||||
assert stdout == ''
|
||||
assert stderr == ''
|
||||
|
||||
|
||||
def test_project_empty_platform(tmpdir):
|
||||
"""
|
||||
import cppcheck project that contains an empty platform type
|
||||
"""
|
||||
project_file = __write_cppcheck_project_file(tmpdir, platform='')
|
||||
|
||||
with open(os.path.join(tmpdir, '1.c'), 'wt') as f:
|
||||
f.write("int x;")
|
||||
|
||||
ret, stdout, stderr = cppcheck(['--platform=native', '--project=' + project_file, '--template=cppcheck1', '-q'])
|
||||
assert ret == 0, stdout
|
||||
assert stdout == ''
|
||||
assert stderr == ''
|
||||
|
||||
|
||||
def test_project_unspecified_platform(tmpdir):
|
||||
"""
|
||||
import cppcheck project that contains the deprecated platform type "Unspecified"
|
||||
"""
|
||||
project_file = __write_cppcheck_project_file(tmpdir, platform='Unspecified')
|
||||
|
||||
with open(os.path.join(tmpdir, '1.c'), 'wt') as f:
|
||||
f.write("int x;")
|
||||
|
||||
ret, stdout, stderr = cppcheck(['--platform=native', '--project=' + project_file, '--template=cppcheck1', '-q'])
|
||||
assert ret == 0, stdout
|
||||
assert stdout == "cppcheck: 'Unspecified' is a deprecated platform type and will be removed in Cppcheck 2.14. Please use 'unspecified' instead.\n"
|
||||
assert stderr == ''
|
||||
|
||||
|
||||
def test_project_unknown_platform(tmpdir):
|
||||
"""
|
||||
import cppcheck project that contains an unknown platform type
|
||||
"""
|
||||
project_file = __write_cppcheck_project_file(tmpdir, platform='dummy')
|
||||
|
||||
with open(os.path.join(tmpdir, '1.c'), 'wt') as f:
|
||||
f.write("int x;")
|
||||
|
||||
ret, stdout, stderr = cppcheck(['--project=' + project_file, '--template=cppcheck1'])
|
||||
assert ret == 1, stdout
|
||||
assert stdout == "cppcheck: error: unrecognized platform: 'dummy'.\n"
|
||||
assert stderr == ''
|
||||
|
||||
|
||||
def test_project_empty_fields(tmpdir):
|
||||
"""
|
||||
import cppcheck project that contains all empty fields - make sure there are no crashes
|
||||
"""
|
||||
project_file = os.path.join(tmpdir, 'Project.cppcheck')
|
||||
|
||||
with open(project_file, 'wt') as f:
|
||||
f.write(
|
||||
"""<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="1">
|
||||
<root/>
|
||||
<builddir/>
|
||||
<includedir/>
|
||||
<includedir>
|
||||
<dir/>
|
||||
</includedir>
|
||||
<defines/>
|
||||
<defines>
|
||||
<define/>
|
||||
</defines>
|
||||
<undefines/>
|
||||
<undefines>
|
||||
<undefine/>
|
||||
</undefines>
|
||||
<importproject/>
|
||||
<paths/>
|
||||
<paths>
|
||||
<dir/>
|
||||
</paths>
|
||||
<exclude/>
|
||||
<exclude>
|
||||
<paths/>
|
||||
</exclude>
|
||||
<function-contracts/>
|
||||
<variable-contracts/>
|
||||
<ignore/>
|
||||
<ignore>
|
||||
<path/>
|
||||
</ignore>
|
||||
<libraries/>
|
||||
<libraries>
|
||||
<library/>
|
||||
</libraries>
|
||||
<suppressions/>
|
||||
<suppressions>
|
||||
<suppression/>
|
||||
</suppressions>
|
||||
<vs-configurations/>
|
||||
<vs-configurations>
|
||||
<config/>
|
||||
</vs-configurations>
|
||||
<platform/>
|
||||
<analyze-all-vs-configs/>
|
||||
<parser/>
|
||||
<addons/>
|
||||
<addons>
|
||||
<addon/>
|
||||
</addons>
|
||||
<tags/>
|
||||
<tools/>
|
||||
<tools>
|
||||
<tool/>
|
||||
</tools>
|
||||
<check-headers/>
|
||||
<check-unused-templates/>
|
||||
<max-ctu-depth/>
|
||||
<max-template-recursion/>
|
||||
<check-unknown-function-return-values/>
|
||||
<safe-checks/>
|
||||
<safe-checks>
|
||||
<class-public/>
|
||||
<external-functions/>
|
||||
<internal-functions/>
|
||||
<external-variables/>
|
||||
</safe-checks>
|
||||
<tag-warnings/>
|
||||
<bug-hunting/>
|
||||
<cert-c-int-precision/>
|
||||
<coding-standards/>
|
||||
<coding-standards>
|
||||
<coding-standard/>
|
||||
</coding-standards>
|
||||
</project>""")
|
||||
|
||||
ret, stdout, stderr = cppcheck(['--platform=native', '--project=' + project_file, '--template=cppcheck1'])
|
||||
assert ret == 1, stdout # do not crash
|
||||
assert stdout == 'cppcheck: error: no C or C++ source files found.\n'
|
||||
assert stderr == ''
|
||||
|
||||
|
||||
def test_project_missing_subproject(tmpdir):
|
||||
"""
|
||||
import cppcheck project that contains an unknown platform type
|
||||
"""
|
||||
project_file = __write_cppcheck_project_file(tmpdir, importproject='dummy.json')
|
||||
|
||||
ret, stdout, stderr = cppcheck(['--project=' + project_file, '--template=cppcheck1'])
|
||||
assert ret == 1, stdout
|
||||
assert stdout == "cppcheck: error: failed to open project '{}/dummy.json'. The file does not exist.\n".format(str(tmpdir).replace('\\', '/'))
|
||||
assert stderr == ''
|
|
@ -56,6 +56,7 @@ def lookup_cppcheck_exe():
|
|||
for path in ('', 'bin/', 'bin/debug/'):
|
||||
exe_path = base + path + exe_name
|
||||
if os.path.isfile(exe_path):
|
||||
print("using '{}'".format(exe_path))
|
||||
return exe_path
|
||||
|
||||
return None
|
||||
|
|
|
@ -1076,7 +1076,7 @@ private:
|
|||
REDIRECT;
|
||||
const char * const argv[] = {"cppcheck", "--platform=win128", "file.cpp"};
|
||||
ASSERT(!defParser.parseFromArgs(3, argv));
|
||||
ASSERT_EQUALS("cppcheck: error: unrecognized platform: \"win128\".\n", GET_REDIRECT_OUTPUT);
|
||||
ASSERT_EQUALS("cppcheck: error: unrecognized platform: 'win128'.\n", GET_REDIRECT_OUTPUT);
|
||||
}
|
||||
|
||||
#if defined(_WIN64) || defined(_WIN32)
|
||||
|
|
Loading…
Reference in New Issue