From 4c650289adb0385e147ff8dada50eab7abcfb9bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Thu, 24 Mar 2022 22:50:04 +0100 Subject: [PATCH] compile_commands.json: ensure that order of include paths are kept --- cmake/clang_tidy.cmake | 4 ++-- lib/importproject.cpp | 24 +++++++++++------------- test/testimportproject.cpp | 26 +++++++++++++++++++++++++- 3 files changed, 38 insertions(+), 16 deletions(-) diff --git a/cmake/clang_tidy.cmake b/cmake/clang_tidy.cmake index 6c9986b04..ecedff056 100644 --- a/cmake/clang_tidy.cmake +++ b/cmake/clang_tidy.cmake @@ -11,11 +11,11 @@ find_program(RUN_CLANG_TIDY NAMES run-clang-tidy run-clang-tidy-13 run-clang-tid message(STATUS "RUN_CLANG_TIDY=${RUN_CLANG_TIDY}") if (RUN_CLANG_TIDY) # disable all compiler warnings since we are just interested in the tidy ones - add_custom_target(run-clang-tidy ${RUN_CLANG_TIDY} -p=${CMAKE_BINARY_DIR} -j ${NPROC} -extra-arg=-w -quiet) + add_custom_target(run-clang-tidy ${RUN_CLANG_TIDY} -checks=-performance-unnecessary-copy-initialization -p=${CMAKE_BINARY_DIR} -j ${NPROC} -extra-arg=-w -quiet) if (BUILD_GUI) add_dependencies(run-clang-tidy gui-build-deps) if (BUILD_TESTS) add_dependencies(run-clang-tidy triage-build-ui-deps) endif() endif() -endif() \ No newline at end of file +endif() diff --git a/lib/importproject.cpp b/lib/importproject.cpp index 91a3089a0..1261bd60d 100644 --- a/lib/importproject.cpp +++ b/lib/importproject.cpp @@ -147,22 +147,21 @@ static bool simplifyPathWithVariables(std::string &s, std::map &in, std::map &variables) { - std::list listInc; - // only parse each includePath once - so remove duplicates - std::list uniqueIncludePaths = in; - uniqueIncludePaths.sort(); - uniqueIncludePaths.unique(); - - for (const std::string &it : uniqueIncludePaths) { - if (it.empty()) + std::set found; + const std::list copyIn(in); + includePaths.clear(); + for (const std::string &ipath : copyIn) { + if (ipath.empty()) continue; - if (it.compare(0,2,"%(")==0) + if (ipath.compare(0,2,"%(")==0) + continue; + std::string s(Path::fromNativeSeparators(ipath)); + if (!found.insert(s).second) continue; - std::string s(Path::fromNativeSeparators(it)); if (s[0] == '/' || (s.size() > 1U && s.compare(1,2,":/") == 0)) { if (!endsWith(s,'/')) s += '/'; - listInc.push_back(s); + includePaths.push_back(s); continue; } @@ -177,9 +176,8 @@ void ImportProject::FileSettings::setIncludePaths(const std::string &basepath, c } if (s.empty()) continue; - listInc.push_back(s + '/'); + includePaths.push_back(s + '/'); } - includePaths.swap(listInc); } ImportProject::Type ImportProject::import(const std::string &filename, Settings *settings) diff --git a/test/testimportproject.cpp b/test/testimportproject.cpp index d10ddfeb3..6430ab0bc 100644 --- a/test/testimportproject.cpp +++ b/test/testimportproject.cpp @@ -60,6 +60,7 @@ private: TEST_CASE(importCompileCommands8); // Windows: "C:\Users\danielm\cppcheck" TEST_CASE(importCompileCommands9); TEST_CASE(importCompileCommands10); // #10887: include path with space + TEST_CASE(importCompileCommands11); // include path order TEST_CASE(importCompileCommandsArgumentsSection); // Handle arguments section TEST_CASE(importCompileCommandsNoCommandSection); // gracefully handles malformed json TEST_CASE(importCppcheckGuiProject); @@ -211,7 +212,8 @@ private: TestImporter importer; importer.importCompileCommands(istr); ASSERT_EQUALS(2, importer.fileSettings.size()); - ASSERT_EQUALS("C:/Users/dan/git/test-cppcheck/mylib/second src/", importer.fileSettings.begin()->includePaths.front()); + ASSERT_EQUALS("C:/Users/dan/git/test-cppcheck/mylib/src/", importer.fileSettings.begin()->includePaths.front()); + ASSERT_EQUALS("C:/Users/dan/git/test-cppcheck/mylib/second src/", importer.fileSettings.begin()->includePaths.back()); } @@ -283,6 +285,28 @@ private: ASSERT_EQUALS("/home/danielm/cppcheck/test folder/", fs.includePaths.front()); } + void importCompileCommands11() const { // include path order + const char json[] = + R"([{ + "file": "1.c" , + "directory": "/x", + "arguments": [ + "cc", + "-I", + "def", + "-I", + "abc" + ] + }])"; + std::istringstream istr(json); + TestImporter importer; + ASSERT_EQUALS(true, importer.importCompileCommands(istr)); + ASSERT_EQUALS(1, importer.fileSettings.size()); + const ImportProject::FileSettings &fs = importer.fileSettings.front(); + ASSERT_EQUALS("/x/def/", fs.includePaths.front()); + ASSERT_EQUALS("/x/abc/", fs.includePaths.back()); + } + void importCompileCommandsArgumentsSection() const { const char json[] = "[ { \"directory\": \"/tmp/\"," "\"arguments\": [\"gcc\", \"-c\", \"src.c\"],"