compile_commands.json: ensure that order of include paths are kept

This commit is contained in:
Daniel Marjamäki 2022-03-24 22:50:04 +01:00
parent 760436c56e
commit 4c650289ad
3 changed files with 38 additions and 16 deletions

View File

@ -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}") message(STATUS "RUN_CLANG_TIDY=${RUN_CLANG_TIDY}")
if (RUN_CLANG_TIDY) if (RUN_CLANG_TIDY)
# disable all compiler warnings since we are just interested in the tidy ones # 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) if (BUILD_GUI)
add_dependencies(run-clang-tidy gui-build-deps) add_dependencies(run-clang-tidy gui-build-deps)
if (BUILD_TESTS) if (BUILD_TESTS)
add_dependencies(run-clang-tidy triage-build-ui-deps) add_dependencies(run-clang-tidy triage-build-ui-deps)
endif() endif()
endif() endif()
endif() endif()

View File

@ -147,22 +147,21 @@ static bool simplifyPathWithVariables(std::string &s, std::map<std::string, std:
void ImportProject::FileSettings::setIncludePaths(const std::string &basepath, const std::list<std::string> &in, std::map<std::string, std::string, cppcheck::stricmp> &variables) void ImportProject::FileSettings::setIncludePaths(const std::string &basepath, const std::list<std::string> &in, std::map<std::string, std::string, cppcheck::stricmp> &variables)
{ {
std::list<std::string> listInc; std::set<std::string> found;
// only parse each includePath once - so remove duplicates const std::list<std::string> copyIn(in);
std::list<std::string> uniqueIncludePaths = in; includePaths.clear();
uniqueIncludePaths.sort(); for (const std::string &ipath : copyIn) {
uniqueIncludePaths.unique(); if (ipath.empty())
for (const std::string &it : uniqueIncludePaths) {
if (it.empty())
continue; 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; continue;
std::string s(Path::fromNativeSeparators(it));
if (s[0] == '/' || (s.size() > 1U && s.compare(1,2,":/") == 0)) { if (s[0] == '/' || (s.size() > 1U && s.compare(1,2,":/") == 0)) {
if (!endsWith(s,'/')) if (!endsWith(s,'/'))
s += '/'; s += '/';
listInc.push_back(s); includePaths.push_back(s);
continue; continue;
} }
@ -177,9 +176,8 @@ void ImportProject::FileSettings::setIncludePaths(const std::string &basepath, c
} }
if (s.empty()) if (s.empty())
continue; continue;
listInc.push_back(s + '/'); includePaths.push_back(s + '/');
} }
includePaths.swap(listInc);
} }
ImportProject::Type ImportProject::import(const std::string &filename, Settings *settings) ImportProject::Type ImportProject::import(const std::string &filename, Settings *settings)

View File

@ -60,6 +60,7 @@ private:
TEST_CASE(importCompileCommands8); // Windows: "C:\Users\danielm\cppcheck" TEST_CASE(importCompileCommands8); // Windows: "C:\Users\danielm\cppcheck"
TEST_CASE(importCompileCommands9); TEST_CASE(importCompileCommands9);
TEST_CASE(importCompileCommands10); // #10887: include path with space TEST_CASE(importCompileCommands10); // #10887: include path with space
TEST_CASE(importCompileCommands11); // include path order
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);
@ -211,7 +212,8 @@ private:
TestImporter importer; TestImporter importer;
importer.importCompileCommands(istr); importer.importCompileCommands(istr);
ASSERT_EQUALS(2, importer.fileSettings.size()); 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()); 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 { void importCompileCommandsArgumentsSection() const {
const char json[] = "[ { \"directory\": \"/tmp/\"," const char json[] = "[ { \"directory\": \"/tmp/\","
"\"arguments\": [\"gcc\", \"-c\", \"src.c\"]," "\"arguments\": [\"gcc\", \"-c\", \"src.c\"],"