From 6cbd69bf2d136816fbbd6f1e31067c6b2be1eb5f Mon Sep 17 00:00:00 2001 From: baltth Date: Tue, 26 Dec 2017 13:04:27 +0100 Subject: [PATCH] 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 --- lib/cppcheck.cpp | 4 +++- lib/importproject.cpp | 26 ++++++++++++++++++++++++-- lib/importproject.h | 3 ++- test/testimportproject.cpp | 21 +++++++++++++++++++++ 4 files changed, 50 insertions(+), 4 deletions(-) diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 8db553636..a859f3b0c 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -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) { diff --git a/lib/importproject.cpp b/lib/importproject.cpp index 9ca0c0766..e14c41ba8 100644 --- a/lib/importproject.cpp +++ b/lib/importproject.cpp @@ -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') diff --git a/lib/importproject.h b/lib/importproject.h index 7901a0790..1aa5e6b3d 100644 --- a/lib/importproject.h +++ b/lib/importproject.h @@ -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 &variables, const std::string &additionalIncludeDirectories); }; diff --git a/test/testimportproject.cpp b/test/testimportproject.cpp index 08812b82d..6831dbc52 100644 --- a/test/testimportproject.cpp +++ b/test/testimportproject.cpp @@ -23,6 +23,14 @@ #include #include +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)