Json: Use simple json library picojson to read compile databases
This commit is contained in:
parent
615903c6be
commit
5f5c33baf2
File diff suppressed because it is too large
Load Diff
|
@ -25,6 +25,7 @@
|
||||||
#include "tokenize.h"
|
#include "tokenize.h"
|
||||||
#include "tokenlist.h"
|
#include "tokenlist.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
#include "../externals/picojson.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
@ -192,41 +193,29 @@ ImportProject::Type ImportProject::import(const std::string &filename)
|
||||||
return UNKNOWN;
|
return UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImportProject::importCompileCommands(std::istream &istr)
|
static std::string readUntil(const std::string &command, std::string::size_type *pos, const char until[])
|
||||||
{
|
{
|
||||||
std::map<std::string, std::string> values;
|
std::string ret;
|
||||||
|
bool str = false;
|
||||||
// TODO: Use a JSON parser
|
while (*pos < command.size() && (str || !std::strchr(until, command[*pos]))) {
|
||||||
|
if (command[*pos] == '\\')
|
||||||
Settings settings;
|
++*pos;
|
||||||
TokenList tokenList(&settings);
|
if (*pos < command.size())
|
||||||
tokenList.createTokens(istr);
|
ret += command[(*pos)++];
|
||||||
for (const Token *tok = tokenList.front(); tok; tok = tok->next()) {
|
if (endsWith(ret, '\"'))
|
||||||
if (Token::Match(tok, "%str% : %str% [,}]")) {
|
str = !str;
|
||||||
const std::string& key = tok->str();
|
|
||||||
const std::string& value = tok->strAt(2);
|
|
||||||
values[key.substr(1, key.size() - 2U)] = value.substr(1, value.size() - 2U);
|
|
||||||
}
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
else if (Token::Match(tok, "%str% : [ %str%") && tok->str() == "\"arguments\"") {
|
void ImportProject::FileSettings::parseCommand(const std::string &command)
|
||||||
std::string cmd;
|
{
|
||||||
tok = tok->tokAt(2);
|
std::string defs;
|
||||||
while (Token::Match(tok, ",|[ %str%")) {
|
|
||||||
const std::string &s = tok->next()->str();
|
|
||||||
cmd += ' ' + s.substr(1, s.size() - 2);
|
|
||||||
tok = tok->tokAt(2);
|
|
||||||
}
|
|
||||||
values["command"] = cmd.substr(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (tok->str() == "}") {
|
// Parse command..
|
||||||
if (!values["file"].empty() && !values["command"].empty()) {
|
|
||||||
struct FileSettings fs;
|
|
||||||
fs.filename = Path::fromNativeSeparators(values["file"]);
|
|
||||||
const std::string& command = values["command"];
|
|
||||||
const std::string directory = Path::fromNativeSeparators(values["directory"]);
|
|
||||||
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))) {
|
||||||
|
while (pos < command.size() && command[pos] == ' ')
|
||||||
pos++;
|
pos++;
|
||||||
if (pos >= command.size())
|
if (pos >= command.size())
|
||||||
break;
|
break;
|
||||||
|
@ -240,54 +229,48 @@ void ImportProject::importCompileCommands(std::istream &istr)
|
||||||
while (pos < command.size() && command[pos] == ' ')
|
while (pos < command.size() && command[pos] == ' ')
|
||||||
++pos;
|
++pos;
|
||||||
}
|
}
|
||||||
std::string fval;
|
const std::string fval = readUntil(command, &pos, " =");
|
||||||
while (pos < command.size() && command[pos] != ' ' && command[pos] != '=') {
|
|
||||||
if (command[pos] != '\\')
|
|
||||||
fval += command[pos];
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
if (F=='D') {
|
if (F=='D') {
|
||||||
std::string defval;
|
const std::string defval = readUntil(command, &pos, " ");
|
||||||
bool str = false;
|
defs += fval;
|
||||||
while (pos < command.size() && (str || command[pos] != ' ')) {
|
|
||||||
if (command.compare(pos, 4, "\\\\\\\"") == 0) {
|
|
||||||
defval += '\"';
|
|
||||||
str = !str;
|
|
||||||
pos += 4;
|
|
||||||
} else {
|
|
||||||
defval += command[pos];
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fs.defines += fval;
|
|
||||||
if (!defval.empty())
|
if (!defval.empty())
|
||||||
fs.defines += defval;
|
defs += defval;
|
||||||
fs.defines += ';';
|
defs += ';';
|
||||||
} else if (F=='U')
|
} else if (F=='U')
|
||||||
fs.undefs.insert(fval);
|
undefs.insert(fval);
|
||||||
else if (F=='I')
|
else if (F=='I')
|
||||||
fs.includePaths.push_back(fval);
|
includePaths.push_back(fval);
|
||||||
else if (F=='s' && fval.compare(0,3,"td=") == 0)
|
else if (F=='s' && fval.compare(0,3,"td=") == 0)
|
||||||
fs.standard = fval.substr(3);
|
standard = fval.substr(3);
|
||||||
else if (F == 'i' && fval == "system") {
|
else if (F == 'i' && fval == "system") {
|
||||||
++pos;
|
++pos;
|
||||||
std::string isystem;
|
const std::string isystem = readUntil(command, &pos, " ");
|
||||||
while (pos < command.size() && command[pos] != ' ') {
|
systemIncludePaths.push_back(isystem);
|
||||||
if (command[pos] != '\\')
|
|
||||||
isystem += command[pos];
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
fs.systemIncludePaths.push_back(isystem);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
setDefines(defs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImportProject::importCompileCommands(std::istream &istr)
|
||||||
|
{
|
||||||
|
picojson::value v;
|
||||||
|
istr >> v;
|
||||||
|
if (!v.is<picojson::array>())
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (const picojson::value &fileInfo : v.get<picojson::array>()) {
|
||||||
|
picojson::object obj = fileInfo.get<picojson::object>();
|
||||||
|
const std::string directory = Path::fromNativeSeparators(obj["directory"].get<std::string>());
|
||||||
|
const std::string command = obj["command"].get<std::string>();
|
||||||
|
const std::string file = Path::fromNativeSeparators(obj["file"].get<std::string>());
|
||||||
|
|
||||||
|
struct FileSettings fs;
|
||||||
|
fs.filename = file;
|
||||||
|
fs.parseCommand(command); // read settings; -D, -I, -U, -std
|
||||||
std::map<std::string, std::string, cppcheck::stricmp> variables;
|
std::map<std::string, std::string, cppcheck::stricmp> variables;
|
||||||
fs.setIncludePaths(directory, fs.includePaths, variables);
|
fs.setIncludePaths(directory, fs.includePaths, variables);
|
||||||
fs.setDefines(fs.defines);
|
|
||||||
fileSettings.push_back(fs);
|
fileSettings.push_back(fs);
|
||||||
}
|
}
|
||||||
values.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImportProject::importSln(std::istream &istr, const std::string &path)
|
void ImportProject::importSln(std::istream &istr, const std::string &path)
|
||||||
|
|
|
@ -73,6 +73,7 @@ public:
|
||||||
bool msc;
|
bool msc;
|
||||||
bool useMfc;
|
bool useMfc;
|
||||||
|
|
||||||
|
void parseCommand(const std::string &command);
|
||||||
void setDefines(std::string defs);
|
void setDefines(std::string defs);
|
||||||
void setIncludePaths(const std::string &basepath, const std::list<std::string> &in, std::map<std::string, std::string, cppcheck::stricmp> &variables);
|
void setIncludePaths(const std::string &basepath, const std::list<std::string> &in, std::map<std::string, std::string, cppcheck::stricmp> &variables);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue