diff options
author | Manuel Klimek <klimek@google.com> | 2011-03-31 23:55:00 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2011-04-25 17:27:59 (GMT) |
commit | 0e6b05fcba61a1b113b841dd2b3e1e5060866d0e (patch) | |
tree | 7c7a2237420f7c6692e7d9d752373d1ceb4ef7cb /Tests/CMakeLib | |
parent | 5674844de4b74d0b66cfc6b8237e631702c43637 (diff) | |
download | CMake-0e6b05fcba61a1b113b841dd2b3e1e5060866d0e.zip CMake-0e6b05fcba61a1b113b841dd2b3e1e5060866d0e.tar.gz CMake-0e6b05fcba61a1b113b841dd2b3e1e5060866d0e.tar.bz2 |
Adds a test for the compile command line output.
Diffstat (limited to 'Tests/CMakeLib')
-rw-r--r-- | Tests/CMakeLib/CMakeLists.txt | 3 | ||||
-rw-r--r-- | Tests/CMakeLib/run_compile_commands.cxx | 132 |
2 files changed, 135 insertions, 0 deletions
diff --git a/Tests/CMakeLib/CMakeLists.txt b/Tests/CMakeLib/CMakeLists.txt index bda2fa5..7815545 100644 --- a/Tests/CMakeLib/CMakeLists.txt +++ b/Tests/CMakeLib/CMakeLists.txt @@ -30,3 +30,6 @@ endif() foreach(test ${CMakeLib_TESTS}) add_test(CMakeLib.${test} CMakeLibTests ${test}) endforeach() + +ADD_EXECUTABLE(runcompilecommands run_compile_commands.cxx) +TARGET_LINK_LIBRARIES(runcompilecommands CMakeLib) diff --git a/Tests/CMakeLib/run_compile_commands.cxx b/Tests/CMakeLib/run_compile_commands.cxx new file mode 100644 index 0000000..c925167 --- /dev/null +++ b/Tests/CMakeLib/run_compile_commands.cxx @@ -0,0 +1,132 @@ +#include "cmSystemTools.h" + +class CompileCommandParser { +public: + typedef std::map<std::string, std::string> CommandType; + 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"); + 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.clear(); + if(!Expect('"')) return; + while (!Expect('"')) + { + Expect('\\'); + this->String.push_back(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 = 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<std::string> std_command; + cmSystemTools::ParseUnixCommandLine(it->at("command").c_str(), std_command); + std::vector<cmStdString> command(std_command.begin(), std_command.end()); + 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; +} |