Skip to content

Commit fd5bc25

Browse files
committed
store ImportProject errors in a vector instead of printing directly
1 parent 98b6ff5 commit fd5bc25

File tree

3 files changed

+37
-25
lines changed

3 files changed

+37
-25
lines changed

cli/cmdlineparser.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1191,14 +1191,17 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
11911191
mSettings.libraries.emplace_back("windows");
11921192
}
11931193
if (projectType == ImportProject::Type::MISSING) {
1194+
project.printErrors();
11941195
mLogger.printError("failed to open project '" + projectFile + "'. The file does not exist.");
11951196
return Result::Fail;
11961197
}
11971198
if (projectType == ImportProject::Type::UNKNOWN) {
1199+
project.printErrors();
11981200
mLogger.printError("failed to load project '" + projectFile + "'. The format is unknown.");
11991201
return Result::Fail;
12001202
}
12011203
if (projectType == ImportProject::Type::FAILURE) {
1204+
project.printErrors();
12021205
mLogger.printError("failed to load project '" + projectFile + "'. An error occurred.");
12031206
return Result::Fail;
12041207
}

lib/importproject.cpp

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ bool ImportProject::importCompileCommands(std::istream &istr)
335335
picojson::value compileCommands;
336336
istr >> compileCommands;
337337
if (!compileCommands.is<picojson::array>()) {
338-
printError("compilation database is not a JSON array");
338+
errors.emplace_back("compilation database is not a JSON array");
339339
return false;
340340
}
341341

@@ -345,12 +345,12 @@ bool ImportProject::importCompileCommands(std::istream &istr)
345345
picojson::object obj = fileInfo.get<picojson::object>();
346346

347347
if (obj.count("directory") == 0) {
348-
printError("'directory' field in compilation database entry missing");
348+
errors.emplace_back("'directory' field in compilation database entry missing");
349349
return false;
350350
}
351351

352352
if (!obj["directory"].is<std::string>()) {
353-
printError("'directory' field in compilation database entry is not a string");
353+
errors.emplace_back("'directory' field in compilation database entry is not a string");
354354
return false;
355355
}
356356

@@ -377,24 +377,24 @@ bool ImportProject::importCompileCommands(std::istream &istr)
377377
}
378378
}
379379
} else {
380-
printError("'arguments' field in compilation database entry is not a JSON array");
380+
errors.emplace_back("'arguments' field in compilation database entry is not a JSON array");
381381
return false;
382382
}
383383
} else if (obj.count("command")) {
384384
doUnescape = true;
385385
if (obj["command"].is<std::string>()) {
386386
command = obj["command"].get<std::string>();
387387
} else {
388-
printError("'command' field in compilation database entry is not a string");
388+
errors.emplace_back("'command' field in compilation database entry is not a string");
389389
return false;
390390
}
391391
} else {
392-
printError("no 'arguments' or 'command' field found in compilation database entry");
392+
errors.emplace_back("no 'arguments' or 'command' field found in compilation database entry");
393393
return false;
394394
}
395395

396396
if (!obj.count("file") || !obj["file"].is<std::string>()) {
397-
printError("skip compilation database entry because it does not have a proper 'file' field");
397+
errors.emplace_back("skip compilation database entry because it does not have a proper 'file' field");
398398
continue;
399399
}
400400

@@ -434,14 +434,14 @@ bool ImportProject::importSln(std::istream &istr, const std::string &path, const
434434
std::string line;
435435

436436
if (!std::getline(istr,line)) {
437-
printError("Visual Studio solution file is empty");
437+
errors.emplace_back("Visual Studio solution file is empty");
438438
return false;
439439
}
440440

441441
if (!startsWith(line, "Microsoft Visual Studio Solution File")) {
442442
// Skip BOM
443443
if (!std::getline(istr, line) || !startsWith(line, "Microsoft Visual Studio Solution File")) {
444-
printError("Visual Studio solution file header not found");
444+
errors.emplace_back("Visual Studio solution file header not found");
445445
return false;
446446
}
447447
}
@@ -466,14 +466,14 @@ bool ImportProject::importSln(std::istream &istr, const std::string &path, const
466466
vcxproj = path + vcxproj;
467467
vcxproj = Path::fromNativeSeparators(std::move(vcxproj));
468468
if (!importVcxproj(vcxproj, variables, "", fileFilters, sharedItemsProjects)) {
469-
printError("failed to load '" + vcxproj + "' from Visual Studio solution");
469+
errors.emplace_back("failed to load '" + vcxproj + "' from Visual Studio solution");
470470
return false;
471471
}
472472
found = true;
473473
}
474474

475475
if (!found) {
476-
printError("no projects found in Visual Studio solution file");
476+
errors.emplace_back("no projects found in Visual Studio solution file");
477477
return false;
478478
}
479479

@@ -730,7 +730,7 @@ bool ImportProject::importVcxproj(const std::string &filename,
730730
tinyxml2::XMLDocument doc;
731731
const tinyxml2::XMLError error = doc.LoadFile(filename.c_str());
732732
if (error != tinyxml2::XML_SUCCESS) {
733-
printError(std::string("Visual Studio project file is not a valid XML - ") + tinyxml2::XMLDocument::ErrorIDToName(error));
733+
errors.emplace_back(std::string("Visual Studio project file is not a valid XML - ") + tinyxml2::XMLDocument::ErrorIDToName(error));
734734
return false;
735735
}
736736
return importVcxproj(filename, doc, variables, additionalIncludeDirectories, fileFilters, cache);
@@ -749,7 +749,7 @@ bool ImportProject::importVcxproj(const std::string &filename, const tinyxml2::X
749749

750750
const tinyxml2::XMLElement * const rootnode = doc.FirstChildElement();
751751
if (rootnode == nullptr) {
752-
printError("Visual Studio project file has no XML root node");
752+
errors.emplace_back("Visual Studio project file has no XML root node");
753753
return false;
754754
}
755755
for (const tinyxml2::XMLElement *node = rootnode->FirstChildElement(); node; node = node->NextSiblingElement()) {
@@ -810,13 +810,13 @@ bool ImportProject::importVcxproj(const std::string &filename, const tinyxml2::X
810810
pathToSharedItemsFile = variables["ProjectDir"] + projectAttribute;
811811
}
812812
if (!simplifyPathWithVariables(pathToSharedItemsFile, variables)) {
813-
printError("Could not simplify path to referenced shared items project");
813+
errors.emplace_back("Could not simplify path to referenced shared items project");
814814
return false;
815815
}
816816

817817
SharedItemsProject toAdd = importVcxitems(pathToSharedItemsFile, fileFilters, cache);
818818
if (!toAdd.successful) {
819-
printError("Could not load shared items project \"" + pathToSharedItemsFile + "\" from original path \"" + std::string(projectAttribute) + "\".");
819+
errors.emplace_back("Could not load shared items project \"" + pathToSharedItemsFile + "\" from original path \"" + std::string(projectAttribute) + "\".");
820820
return false;
821821
}
822822
sharedItemsProjects.emplace_back(toAdd);
@@ -928,12 +928,12 @@ ImportProject::SharedItemsProject ImportProject::importVcxitems(const std::strin
928928
tinyxml2::XMLDocument doc;
929929
const tinyxml2::XMLError error = doc.LoadFile(filename.c_str());
930930
if (error != tinyxml2::XML_SUCCESS) {
931-
printError(std::string("Visual Studio project file is not a valid XML - ") + tinyxml2::XMLDocument::ErrorIDToName(error));
931+
errors.emplace_back(std::string("Visual Studio project file is not a valid XML - ") + tinyxml2::XMLDocument::ErrorIDToName(error));
932932
return result;
933933
}
934934
const tinyxml2::XMLElement * const rootnode = doc.FirstChildElement();
935935
if (rootnode == nullptr) {
936-
printError("Visual Studio project file has no XML root node");
936+
errors.emplace_back("Visual Studio project file has no XML root node");
937937
return result;
938938
}
939939
for (const tinyxml2::XMLElement *node = rootnode->FirstChildElement(); node; node = node->NextSiblingElement()) {
@@ -951,7 +951,7 @@ ImportProject::SharedItemsProject ImportProject::importVcxitems(const std::strin
951951

952952
result.sourceFiles.emplace_back(file);
953953
} else {
954-
printError("Could not find shared items source file");
954+
errors.emplace_back("Could not find shared items source file");
955955
return result;
956956
}
957957
}
@@ -979,12 +979,12 @@ bool ImportProject::importBcb6Prj(const std::string &projectFilename)
979979
tinyxml2::XMLDocument doc;
980980
const tinyxml2::XMLError error = doc.LoadFile(projectFilename.c_str());
981981
if (error != tinyxml2::XML_SUCCESS) {
982-
printError(std::string("Borland project file is not a valid XML - ") + tinyxml2::XMLDocument::ErrorIDToName(error));
982+
errors.emplace_back(std::string("Borland project file is not a valid XML - ") + tinyxml2::XMLDocument::ErrorIDToName(error));
983983
return false;
984984
}
985985
const tinyxml2::XMLElement * const rootnode = doc.FirstChildElement();
986986
if (rootnode == nullptr) {
987-
printError("Borland project file has no XML root node");
987+
errors.emplace_back("Borland project file has no XML root node");
988988
return false;
989989
}
990990

@@ -1296,12 +1296,12 @@ bool ImportProject::importCppcheckGuiProject(std::istream &istr, Settings &setti
12961296
const std::string xmldata = istream_to_string(istr);
12971297
const tinyxml2::XMLError error = doc.Parse(xmldata.data(), xmldata.size());
12981298
if (error != tinyxml2::XML_SUCCESS) {
1299-
printError(std::string("Cppcheck GUI project file is not a valid XML - ") + tinyxml2::XMLDocument::ErrorIDToName(error));
1299+
errors.emplace_back(std::string("Cppcheck GUI project file is not a valid XML - ") + tinyxml2::XMLDocument::ErrorIDToName(error));
13001300
return false;
13011301
}
13021302
const tinyxml2::XMLElement * const rootnode = doc.FirstChildElement();
13031303
if (rootnode == nullptr || strcmp(rootnode->Name(), CppcheckXml::ProjectElementName) != 0) {
1304-
printError("Cppcheck GUI project file has no XML root node");
1304+
errors.emplace_back("Cppcheck GUI project file has no XML root node");
13051305
return false;
13061306
}
13071307

@@ -1420,7 +1420,7 @@ bool ImportProject::importCppcheckGuiProject(std::istream &istr, Settings &setti
14201420
else if (strcmp(childname, Settings::SafeChecks::XmlExternalVariables) == 0)
14211421
temp.safeChecks.externalVariables = true;
14221422
else {
1423-
printError("Unknown '" + std::string(Settings::SafeChecks::XmlRootName) + "' element '" + childname + "' in Cppcheck project file");
1423+
errors.emplace_back("Unknown '" + std::string(Settings::SafeChecks::XmlRootName) + "' element '" + childname + "' in Cppcheck project file");
14241424
return false;
14251425
}
14261426
}
@@ -1443,7 +1443,7 @@ bool ImportProject::importCppcheckGuiProject(std::istream &istr, Settings &setti
14431443
else if (strcmp(name, CppcheckXml::ProjectNameElementName) == 0)
14441444
; // no-op
14451445
else {
1446-
printError("Unknown element '" + std::string(name) + "' in Cppcheck project file");
1446+
errors.emplace_back("Unknown element '" + std::string(name) + "' in Cppcheck project file");
14471447
return false;
14481448
}
14491449
}
@@ -1548,6 +1548,12 @@ void ImportProject::setRelativePaths(const std::string &filename)
15481548
}
15491549
}
15501550

1551+
void ImportProject::printErrors()
1552+
{
1553+
for (const auto &error : errors)
1554+
printError(error);
1555+
}
1556+
15511557
void ImportProject::printError(const std::string &message)
15521558
{
15531559
std::cout << "cppcheck: error: " << message << std::endl;

lib/importproject.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ class CPPCHECKLIB WARN_UNUSED ImportProject {
7474
static void fsSetIncludePaths(FileSettings& fs, const std::string &basepath, const std::list<std::string> &in, std::map<std::string, std::string, cppcheck::stricmp> &variables);
7575

7676
std::list<FileSettings> fileSettings;
77+
std::vector<std::string> errors;
7778

7879
ImportProject() = default;
7980
virtual ~ImportProject() = default;
@@ -98,6 +99,8 @@ class CPPCHECKLIB WARN_UNUSED ImportProject {
9899
void ignorePaths(const std::vector<std::string> &ipaths, bool debug = false);
99100
void ignoreOtherConfigs(const std::string &cfg);
100101

102+
void printErrors();
103+
101104
Type import(const std::string &filename, Settings *settings=nullptr, Suppressions *supprs=nullptr);
102105
protected:
103106
bool importCompileCommands(std::istream &istr);
@@ -112,7 +115,7 @@ class CPPCHECKLIB WARN_UNUSED ImportProject {
112115
};
113116

114117
bool importSln(std::istream &istr, const std::string &path, const std::vector<std::string> &fileFilters);
115-
static SharedItemsProject importVcxitems(const std::string &filename, const std::vector<std::string> &fileFilters, std::vector<SharedItemsProject> &cache);
118+
SharedItemsProject importVcxitems(const std::string &filename, const std::vector<std::string> &fileFilters, std::vector<SharedItemsProject> &cache);
116119
bool importVcxproj(const std::string &filename, std::map<std::string, std::string, cppcheck::stricmp> &variables, const std::string &additionalIncludeDirectories, const std::vector<std::string> &fileFilters, std::vector<SharedItemsProject> &cache);
117120
bool importVcxproj(const std::string &filename, const tinyxml2::XMLDocument &doc, std::map<std::string, std::string, cppcheck::stricmp> &variables, const std::string &additionalIncludeDirectories, const std::vector<std::string> &fileFilters, std::vector<SharedItemsProject> &cache);
118121
bool importBcb6Prj(const std::string &projectFilename);

0 commit comments

Comments
 (0)