| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- #include "cmSystemTools.h"
- class CompileCommandParser {
- public:
- class CommandType: public std::map<cmStdString, cmStdString>
- {
- public:
- cmStdString const& at(cmStdString const& k) const
- {
- const_iterator i = this->find(k);
- if(i != this->end()) { return i->second; }
- static cmStdString emptyString;
- return emptyString;
- }
- };
- typedef std::vector<CommandType> TranslationUnitsType;
- CompileCommandParser(std::ifstream *input)
- {
- this->Input = input;
- }
- void Parse()
- {
- NextNonWhitespace();
- ParseTranslationUnits();
- }
- const TranslationUnitsType& GetTranslationUnits()
- {
- return this->TranslationUnits;
- }
- private:
- void ParseTranslationUnits()
- {
- this->TranslationUnits = TranslationUnitsType();
- ExpectOrDie('[', "at start of compile command file\n");
- do
- {
- ParseTranslationUnit();
- this->TranslationUnits.push_back(this->Command);
- } while(Expect(','));
- ExpectOrDie(']', "at end of array");
- }
- void ParseTranslationUnit()
- {
- this->Command = CommandType();
- if(!Expect('{')) return;
- if(Expect('}')) return;
- do
- {
- ParseString();
- std::string name = this->String;
- ExpectOrDie(':', "between name and value");
- ParseString();
- std::string value = this->String;
- this->Command[name] = value;
- } while(Expect(','));
- ExpectOrDie('}', "at end of object");
- }
- void ParseString()
- {
- this->String = "";
- if(!Expect('"')) return;
- while (!Expect('"'))
- {
- Expect('\\');
- this->String.append(1,C);
- Next();
- }
- }
- bool Expect(char c)
- {
- if(this->C == c)
- {
- NextNonWhitespace();
- return true;
- }
- return false;
- }
- void ExpectOrDie(char c, const std::string & message)
- {
- if (!Expect(c))
- ErrorExit(std::string("'") + c + "' expected " + message + ".");
- }
- void NextNonWhitespace()
- {
- do { Next(); } while (IsWhitespace());
- }
- void Next()
- {
- this->C = char(Input->get());
- if (this->Input->bad()) ErrorExit("Unexpected end of file.");
- }
- void ErrorExit(const std::string &message) {
- std::cout << "ERROR: " << message;
- exit(1);
- }
- bool IsWhitespace()
- {
- return (this->C == ' ' || this->C == '\t' ||
- this->C == '\n' || this->C == '\r');
- }
- char C;
- TranslationUnitsType TranslationUnits;
- CommandType Command;
- std::string String;
- std::ifstream *Input;
- };
- int main ()
- {
- std::ifstream file("compile_commands.json");
- CompileCommandParser parser(&file);
- parser.Parse();
- for(CompileCommandParser::TranslationUnitsType::const_iterator
- it = parser.GetTranslationUnits().begin(),
- end = parser.GetTranslationUnits().end(); it != end; ++it)
- {
- std::vector<cmStdString> command;
- cmSystemTools::ParseUnixCommandLine(it->at("command").c_str(), command);
- if (!cmSystemTools::RunSingleCommand(
- command, 0, 0, it->at("directory").c_str()))
- {
- std::cout << "ERROR: Failed to run command \""
- << command[0] << "\"" << std::endl;
- exit(1);
- }
- }
- return 0;
- }
|