Skip to content

Commit 7287ffe

Browse files
bbennettsdanmar
authored andcommitted
Handle 'arguments' sections in compile_commands.json (danmar#1797)
* Handle 'arguments' sections in compile_commands.json Previous code assumes 'commands' exists and ill assert if t does not. * Correct typo checking for "arguments" rather than "commands" * Use ostringstring rather than stringstream * Add test deominstrating graceful degradation * Add test for parsing "arguments" rather than "commands"
1 parent 9a563a7 commit 7287ffe

File tree

2 files changed

+47
-2
lines changed

2 files changed

+47
-2
lines changed

lib/importproject.cpp

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
#include <cstring>
3131
#include <fstream>
3232
#include <utility>
33-
33+
#include <sstream>
3434

3535
void ImportProject::ignorePaths(const std::vector<std::string> &ipaths)
3636
{
@@ -340,7 +340,30 @@ void ImportProject::importCompileCommands(std::istream &istr)
340340
dirpath += '/';
341341

342342
const std::string directory = dirpath;
343-
const std::string command = obj["command"].get<std::string>();
343+
344+
std::ostringstream comm;
345+
if( obj.find( "arguments" ) != obj.end() ) {
346+
if( obj[ "arguments" ].is< picojson::array >() ) {
347+
for( const picojson::value& arg : obj[ "arguments" ].get< picojson::array >() ) {
348+
if( arg.is< std::string >() ) {
349+
comm << arg.get< std::string >() << " ";
350+
}
351+
}
352+
}
353+
else {
354+
return;
355+
}
356+
}
357+
else if( obj.find( "command" ) != obj.end() ) {
358+
if( obj[ "command" ].is< std::string >() ) {
359+
comm << obj[ "command" ].get< std::string >();
360+
}
361+
}
362+
else {
363+
return;
364+
}
365+
366+
const std::string command = comm.str();
344367
const std::string file = Path::fromNativeSeparators(obj["file"].get<std::string>());
345368

346369
// Accept file?

test/testimportproject.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ class TestImportProject : public TestFixture {
4747
TEST_CASE(importCompileCommands2); // #8563
4848
TEST_CASE(importCompileCommands3); // check with existing trailing / in directory
4949
TEST_CASE(importCompileCommands4); // only accept certain file types
50+
TEST_CASE(importCompileCommandsArgumentsSection); // Handle arguments section
51+
TEST_CASE(importCompileCommandsNoCommandSection); // gracefully handles malformed json
5052
TEST_CASE(importCppcheckGuiProject);
5153
}
5254

@@ -138,6 +140,26 @@ class TestImportProject : public TestFixture {
138140
ASSERT_EQUALS(0, importer.fileSettings.size());
139141
}
140142

143+
void importCompileCommandsArgumentsSection() const {
144+
const char json[] = "[ { \"directory\": \"/tmp/\","
145+
"\"arguments\": [\"gcc\", \"-c\", \"src.c\"],"
146+
"\"file\": \"src.c\" } ]";
147+
std::istringstream istr(json);
148+
TestImporter importer;
149+
importer.importCompileCommands(istr);
150+
ASSERT_EQUALS(1, importer.fileSettings.size());
151+
ASSERT_EQUALS("/tmp/src.c", importer.fileSettings.begin()->filename);
152+
}
153+
154+
void importCompileCommandsNoCommandSection() const {
155+
const char json[] = "[ { \"directory\": \"/tmp/\","
156+
"\"file\": \"src.mm\" } ]";
157+
std::istringstream istr(json);
158+
TestImporter importer;
159+
importer.importCompileCommands(istr);
160+
ASSERT_EQUALS(0, importer.fileSettings.size());
161+
}
162+
141163
void importCppcheckGuiProject() const {
142164
const char xml[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
143165
"<project version=\"1\">\n"

0 commit comments

Comments
 (0)