Import project: do not crash when importing compile database generated by IAR workbench

This commit is contained in:
Daniel Marjamäki 2022-02-16 08:34:33 +01:00
parent 12c1c081dc
commit c968aeaf73
2 changed files with 29 additions and 11 deletions

View File

@ -409,28 +409,35 @@ bool ImportProject::importCompileCommands(std::istream &istr)
const std::string directory = dirpath; const std::string directory = dirpath;
std::ostringstream comm; std::string command;
if (obj.find("arguments") != obj.end()) { if (obj.count("arguments")) {
if (obj["arguments"].is<picojson::array>()) { if (obj["arguments"].is<picojson::array>()) {
for (const picojson::value& arg : obj["arguments"].get<picojson::array>()) { for (const picojson::value& arg : obj["arguments"].get<picojson::array>()) {
if (arg.is<std::string>()) { if (arg.is<std::string>()) {
comm << arg.get<std::string>() << " "; command += arg.get<std::string>() + " ";
} }
} }
} else { } else {
printError("'arguments' field in compilation database entry is not a JSON array"); printError("'arguments' field in compilation database entry is not a JSON array");
return false; return false;
} }
} else if (obj.find("command") != obj.end()) { } else if (obj.count("command")) {
if (obj["command"].is<std::string>()) { if (obj["command"].is<std::string>()) {
comm << obj["command"].get<std::string>(); command = obj["command"].get<std::string>();
} else {
printError("'command' field in compilation database entry is not a string");
return false;
} }
} else { } else {
printError("no 'arguments' or 'command' field found in compilation database entry"); printError("no 'arguments' or 'command' field found in compilation database entry");
return false; return false;
} }
const std::string command = comm.str(); if (!obj.count("file") || !obj["file"].is<std::string>()) {
printError("skip compilation database entry because it does not have a proper 'file' field");
continue;
}
const std::string file = Path::fromNativeSeparators(obj["file"].get<std::string>()); const std::string file = Path::fromNativeSeparators(obj["file"].get<std::string>());
// Accept file? // Accept file?

View File

@ -57,6 +57,7 @@ private:
TEST_CASE(importCompileCommands6); // Windows/CMake/Ninja generated comile_commands.json with spaces TEST_CASE(importCompileCommands6); // Windows/CMake/Ninja generated comile_commands.json with spaces
TEST_CASE(importCompileCommands7); // linux: "/home/danielm/cppcheck 2" TEST_CASE(importCompileCommands7); // linux: "/home/danielm/cppcheck 2"
TEST_CASE(importCompileCommands8); // Windows: "C:\Users\danielm\cppcheck" TEST_CASE(importCompileCommands8); // Windows: "C:\Users\danielm\cppcheck"
TEST_CASE(importCompileCommands9);
TEST_CASE(importCompileCommandsArgumentsSection); // Handle arguments section TEST_CASE(importCompileCommandsArgumentsSection); // Handle arguments section
TEST_CASE(importCompileCommandsNoCommandSection); // gracefully handles malformed json TEST_CASE(importCompileCommandsNoCommandSection); // gracefully handles malformed json
TEST_CASE(importCppcheckGuiProject); TEST_CASE(importCppcheckGuiProject);
@ -242,12 +243,22 @@ private:
}])"; }])";
std::istringstream istr(json); std::istringstream istr(json);
TestImporter importer; TestImporter importer;
importer.importCompileCommands(istr); // Do not crash
}
void importCompileCommands9() const {
// IAR output (https://sourceforge.net/p/cppcheck/discussion/general/thread/608af51e0a/)
const char json[] =
R"([{
"arguments" : [
"powershell.exe -WindowStyle Hidden -NoProfile -ExecutionPolicy Bypass -File d:\\Projekte\\xyz\\firmware\\app\\xyz-lib\\build.ps1 -IAR -COMPILER_PATH \"c:\\Program Files (x86)\\IAR Systems\\Embedded Workbench 9.0\" -CONTROLLER CC1310F128 -LIB LIB_PERMANENT -COMPILER_DEFINES \"CC1310_HFXO_FREQ=24000000 DEBUG\""
],
"directory" : "d:\\Projekte\\xyz\\firmware\\app",
"type" : "PRE"
}])";
std::istringstream istr(json);
TestImporter importer;
importer.importCompileCommands(istr); importer.importCompileCommands(istr);
ASSERT_EQUALS(1, importer.fileSettings.size());
ASSERT_EQUALS("FILESDIR=\"C:\\Program Files\\Cppcheck\"", importer.fileSettings.begin()->defines);
ASSERT_EQUALS(2, importer.fileSettings.begin()->includePaths.size());
ASSERT_EQUALS("C:/Users/danielm/cppcheck/build/lib/", importer.fileSettings.begin()->includePaths.front());
ASSERT_EQUALS("C:/Users/danielm/cppcheck/lib/", importer.fileSettings.begin()->includePaths.back());
} }
void importCompileCommandsArgumentsSection() const { void importCompileCommandsArgumentsSection() const {