ImportProject: Fixed compile_commands.json problems
This commit is contained in:
parent
87379683e0
commit
f700d81e59
|
@ -220,22 +220,27 @@ ImportProject::Type ImportProject::import(const std::string &filename, Settings
|
||||||
static std::string readUntil(const std::string &command, std::string::size_type *pos, const char until[])
|
static std::string readUntil(const std::string &command, std::string::size_type *pos, const char until[])
|
||||||
{
|
{
|
||||||
std::string ret;
|
std::string ret;
|
||||||
|
bool escapedString = false;
|
||||||
bool str = false;
|
bool str = false;
|
||||||
bool escape = false;
|
bool escape = false;
|
||||||
for (; *pos < command.size() && (str || !std::strchr(until, command[*pos])); (*pos)++) {
|
for (; *pos < command.size() && (str || !std::strchr(until, command[*pos])); (*pos)++) {
|
||||||
if (escape) {
|
if (escape)
|
||||||
escape = false;
|
escape = false;
|
||||||
if (!std::strchr("\\\"\'", command[*pos]))
|
else if (command[*pos] == '\\') {
|
||||||
ret += '\\';
|
if (str)
|
||||||
ret += command[*pos];
|
|
||||||
} else if (str && command[*pos] == '\\')
|
|
||||||
escape = true;
|
escape = true;
|
||||||
else {
|
else if (command[*pos + 1] == '"') {
|
||||||
if (command[*pos] == '\"')
|
if (escapedString)
|
||||||
|
return ret + "\\\"";
|
||||||
|
escapedString = true;
|
||||||
|
ret += "\\\"";
|
||||||
|
(*pos)++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else if (command[*pos] == '\"')
|
||||||
str = !str;
|
str = !str;
|
||||||
ret += command[*pos];
|
ret += command[*pos];
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,6 +251,8 @@ static std::string unescape(const std::string &in)
|
||||||
for (char c: in) {
|
for (char c: in) {
|
||||||
if (escape) {
|
if (escape) {
|
||||||
escape = false;
|
escape = false;
|
||||||
|
if (!std::strchr("\\\"\'",c))
|
||||||
|
out += "\\";
|
||||||
out += c;
|
out += c;
|
||||||
} else if (c == '\\')
|
} else if (c == '\\')
|
||||||
escape = true;
|
escape = true;
|
||||||
|
@ -259,8 +266,6 @@ void ImportProject::FileSettings::parseCommand(std::string command)
|
||||||
{
|
{
|
||||||
std::string defs;
|
std::string defs;
|
||||||
|
|
||||||
command = unescape(command);
|
|
||||||
|
|
||||||
// Parse command..
|
// Parse command..
|
||||||
std::string::size_type pos = 0;
|
std::string::size_type pos = 0;
|
||||||
while (std::string::npos != (pos = command.find(' ',pos))) {
|
while (std::string::npos != (pos = command.find(' ',pos))) {
|
||||||
|
@ -280,8 +285,12 @@ void ImportProject::FileSettings::parseCommand(std::string command)
|
||||||
}
|
}
|
||||||
const std::string fval = readUntil(command, &pos, " =");
|
const std::string fval = readUntil(command, &pos, " =");
|
||||||
if (F=='D') {
|
if (F=='D') {
|
||||||
const std::string defval = readUntil(command, &pos, " ");
|
std::string defval = readUntil(command, &pos, " ");
|
||||||
defs += fval;
|
defs += fval;
|
||||||
|
if (defval.size() >= 3 && defval.compare(0,2,"=\"")==0 && defval.back()=='\"')
|
||||||
|
defval = "=" + unescape(defval.substr(2, defval.size() - 3));
|
||||||
|
else if (defval.size() >= 5 && defval.compare(0,3,"=\\\"")==0 && endsWith(defval,"\\\"",2))
|
||||||
|
defval = "=\"" + unescape(defval.substr(3, defval.size() - 5)) + "\"";
|
||||||
if (!defval.empty())
|
if (!defval.empty())
|
||||||
defs += defval;
|
defs += defval;
|
||||||
defs += ';';
|
defs += ';';
|
||||||
|
|
|
@ -50,6 +50,7 @@ private:
|
||||||
TEST_CASE(importCompileCommands5); // Windows/CMake/Ninja generated comile_commands.json
|
TEST_CASE(importCompileCommands5); // Windows/CMake/Ninja generated comile_commands.json
|
||||||
TEST_CASE(importCompileCommands6); // Windows/CMake/Ninja generated comile_commands.json with spaces
|
TEST_CASE(importCompileCommands6); // Windows/CMake/Ninja generated comile_commands.json with spaces
|
||||||
TEST_CASE(importCompileCommands7); // linux: "/home/danielm/cppcheck 2"
|
TEST_CASE(importCompileCommands7); // linux: "/home/danielm/cppcheck 2"
|
||||||
|
TEST_CASE(importCompileCommands8); // Windows: "C:\Users\danielm\cppcheck"
|
||||||
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);
|
||||||
|
@ -153,7 +154,6 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void importCompileCommands5() const {
|
void importCompileCommands5() const {
|
||||||
/* TODO I am not sure if these are escaped properly
|
|
||||||
const char json[] =
|
const char json[] =
|
||||||
R"([{
|
R"([{
|
||||||
"directory": "C:/Users/dan/git/build-test-cppcheck-Desktop_Qt_5_15_0_MSVC2019_64bit-Debug",
|
"directory": "C:/Users/dan/git/build-test-cppcheck-Desktop_Qt_5_15_0_MSVC2019_64bit-Debug",
|
||||||
|
@ -170,11 +170,9 @@ private:
|
||||||
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/src/", importer.fileSettings.begin()->includePaths.front());
|
ASSERT_EQUALS("C:/Users/dan/git/test-cppcheck/mylib/src/", importer.fileSettings.begin()->includePaths.front());
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void importCompileCommands6() const {
|
void importCompileCommands6() const {
|
||||||
/* TODO I am not sure if these are escaped properly
|
|
||||||
const char json[] =
|
const char json[] =
|
||||||
R"([{
|
R"([{
|
||||||
"directory": "C:/Users/dan/git/build-test-cppcheck-Desktop_Qt_5_15_0_MSVC2019_64bit-Debug",
|
"directory": "C:/Users/dan/git/build-test-cppcheck-Desktop_Qt_5_15_0_MSVC2019_64bit-Debug",
|
||||||
|
@ -191,7 +189,6 @@ private:
|
||||||
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/second src/", importer.fileSettings.begin()->includePaths.front());
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -213,6 +210,24 @@ private:
|
||||||
// TODO ASSERT_EQUALS("/home/danielm/cppcheck 2/externals/", importer.fileSettings.begin()->includePaths.back());
|
// TODO ASSERT_EQUALS("/home/danielm/cppcheck 2/externals/", importer.fileSettings.begin()->includePaths.back());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void importCompileCommands8() const {
|
||||||
|
// cmake -DFILESDIR="C:\Program Files\Cppcheck" -G"NMake Makefiles" ..
|
||||||
|
const char json[] =
|
||||||
|
R"([{
|
||||||
|
"directory": "C:/Users/danielm/cppcheck/build/lib",
|
||||||
|
"command": "C:\\PROGRA~2\\MICROS~2\\2017\\COMMUN~1\\VC\\Tools\\MSVC\\1412~1.258\\bin\\Hostx64\\x64\\cl.exe /nologo /TP -DFILESDIR=\"\\\"C:\\Program Files\\Cppcheck\\\"\" -IC:\\Users\\danielm\\cppcheck\\build\\lib -IC:\\Users\\danielm\\cppcheck\\lib -c C:\\Users\\danielm\\cppcheck\\lib\\astutils.cpp",
|
||||||
|
"file": "C:/Users/danielm/cppcheck/lib/astutils.cpp"
|
||||||
|
}])";
|
||||||
|
std::istringstream istr(json);
|
||||||
|
TestImporter importer;
|
||||||
|
importer.importCompileCommands(istr);
|
||||||
|
ASSERT_EQUALS(1, importer.fileSettings.size());
|
||||||
|
ASSERT_EQUALS("FILESDIR=\"C:\\Program Files\\Cppcheck\"", importer.fileSettings.begin()->defines);
|
||||||
|
ASSERT_EQUALS(2, importer.fileSettings.begin()->includePaths.size());
|
||||||
|
ASSERT_EQUALS("C:/Users/danielm/cppcheck/build/lib/", importer.fileSettings.begin()->includePaths.front());
|
||||||
|
ASSERT_EQUALS("C:/Users/danielm/cppcheck/lib/", importer.fileSettings.begin()->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\"],"
|
||||||
|
|
Loading…
Reference in New Issue