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}")
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()
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)
{
std::list<std::string> listInc;
// only parse each includePath once - so remove duplicates
std::list<std::string> uniqueIncludePaths = in;
uniqueIncludePaths.sort();
uniqueIncludePaths.unique();
for (const std::string &it : uniqueIncludePaths) {
if (it.empty())
std::set<std::string> found;
const std::list<std::string> 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)

View File

@ -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\"],"