Fix define parsing from compile_command.json (#1013)

* Define value parsing from compile_commands.json

* Handle escaping in defined values

* Added test for importCompileCommands

* Added used defines for imported projects

* Fixed unnecessary string literals
This commit is contained in:
baltth 2017-12-26 13:04:27 +01:00 committed by Daniel Marjamäki
parent ede446780e
commit 6cbd69bf2d
4 changed files with 50 additions and 4 deletions

View File

@ -93,7 +93,9 @@ unsigned int CppCheck::check(const ImportProject::FileSettings &fs)
{
CppCheck temp(_errorLogger, _useGlobalSuppressions);
temp._settings = _settings;
temp._settings.userDefines = fs.cppcheckDefines();
if (!temp._settings.userDefines.empty())
temp._settings.userDefines += ';';
temp._settings.userDefines += fs.cppcheckDefines();
temp._settings.includePaths = fs.includePaths;
// TODO: temp._settings.userUndefs = fs.undefs;
if (fs.platformType != Settings::Unspecified) {

View File

@ -222,8 +222,30 @@ void ImportProject::importCompileCommands(std::istream &istr)
fval += command[pos];
pos++;
}
if (F=='D')
fs.defines += fval + ";";
if (F=='D') {
std::string defval;
bool escape = false;
while (pos < command.size() && command[pos] != ' ') {
if (command[pos] != '\\') {
defval += command[pos];
escape = false;
}
else {
if (escape) {
defval += '\\';
escape = false;
}
else {
escape = true;
}
}
pos++;
}
fs.defines += fval;
if (!defval.empty())
fs.defines += defval;
fs.defines += ';';
}
else if (F=='U')
fs.undefs.insert(fval);
else if (F=='I')

View File

@ -74,8 +74,9 @@ public:
void ignoreOtherPlatforms(cppcheck::Platform::PlatformType platformType);
void import(const std::string &filename);
private:
protected:
void importCompileCommands(std::istream &istr);
private:
void importSln(std::istream &istr, const std::string &path);
void importVcxproj(const std::string &filename, std::map<std::string, std::string, cppcheck::stricmp> &variables, const std::string &additionalIncludeDirectories);
};

View File

@ -23,6 +23,14 @@
#include <map>
#include <string>
class TestImporter : public ImportProject {
public:
void importCompileCommands(std::istream &istr) {
ImportProject::importCompileCommands(istr);
}
};
class TestImportProject : public TestFixture {
public:
TestImportProject() : TestFixture("TestImportProject") {
@ -35,6 +43,7 @@ private:
TEST_CASE(setIncludePaths1);
TEST_CASE(setIncludePaths2);
TEST_CASE(setIncludePaths3); // macro names are case insensitive
TEST_CASE(importCompileCommands);
}
void setDefines() const {
@ -84,6 +93,18 @@ private:
ASSERT_EQUALS(1U, fs.includePaths.size());
ASSERT_EQUALS("c:/abc/other/", fs.includePaths.front());
}
void importCompileCommands() const {
const char json[] = "[ { \"directory\": \"/tmp\","
"\"command\": \"gcc -I/tmp -DTEST1 -DTEST2=2 -DTEST3=\\\"\\\\\\\"3\\\\\\\"\\\" -o /tmp/src.o -c /tmp/src.c\","
"\"file\": \"/tmp/src.c\" } ]";
std::istringstream istr(json);
TestImporter importer;
importer.importCompileCommands(istr);
ASSERT_EQUALS(1, importer.fileSettings.size());
ASSERT_EQUALS("TEST1=1;TEST2=2;TEST3=\"\\\"3\\\"\"", importer.fileSettings.begin()->defines);
}
};
REGISTER_TEST(TestImportProject)