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 | |
parent | 5674844de4b74d0b66cfc6b8237e631702c43637 (diff) | |
download | CMake-0e6b05fcba61a1b113b841dd2b3e1e5060866d0e.zip CMake-0e6b05fcba61a1b113b841dd2b3e1e5060866d0e.tar.gz CMake-0e6b05fcba61a1b113b841dd2b3e1e5060866d0e.tar.bz2 |
Adds a test for the compile command line output.
-rw-r--r-- | Tests/CMakeLib/CMakeLists.txt | 3 | ||||
-rw-r--r-- | Tests/CMakeLib/run_compile_commands.cxx | 132 | ||||
-rw-r--r-- | Tests/CMakeLists.txt | 3 | ||||
-rw-r--r-- | Tests/CompileCommandOutput/CMakeLists.txt | 11 | ||||
-rw-r--r-- | Tests/CompileCommandOutput/compile_command_output.cxx | 9 | ||||
-rw-r--r-- | Tests/CompileCommandOutput/file with spaces.cxx | 3 | ||||
-rw-r--r-- | Tests/CompileCommandOutput/file with spaces.h | 1 | ||||
-rw-r--r-- | Tests/CompileCommandOutput/relative.cxx | 3 | ||||
-rw-r--r-- | Tests/CompileCommandOutput/relative.h | 1 |
9 files changed, 166 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; +} diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 157814e..126eadd 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -2031,6 +2031,9 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ ENDIF() SET_TESTS_PROPERTIES(Contracts.${project} PROPERTIES TIMEOUT ${timeout}) ENDFOREACH() + + ADD_TEST_MACRO(CompileCommandOutput + "${CMake_BINARY_DIR}/Tests/CMakeLib/runcompilecommands") ENDIF(BUILD_TESTING) SUBDIRS(CMakeTests) diff --git a/Tests/CompileCommandOutput/CMakeLists.txt b/Tests/CompileCommandOutput/CMakeLists.txt new file mode 100644 index 0000000..ac39b8b --- /dev/null +++ b/Tests/CompileCommandOutput/CMakeLists.txt @@ -0,0 +1,11 @@ +# a simple C only test case +cmake_minimum_required (VERSION 2.6) +project (CompileCommandOutput CXX) + +SET(CMAKE_EXPORT_COMPILE_COMMANDS ON) +set(CMAKE_DEBUG_POSTFIX "_test_debug_postfix") +ADD_LIBRARY(test1 STATIC "file with spaces.cxx") +ADD_LIBRARY(test2 SHARED "../CompileCommandOutput/relative.cxx") +INCLUDE_DIRECTORIES(${CompileCommandOutput_SOURCE_DIR}/../../Source) +ADD_EXECUTABLE(CompileCommandOutput compile_command_output.cxx) +TARGET_LINK_LIBRARIES(CompileCommandOutput test1 test2) diff --git a/Tests/CompileCommandOutput/compile_command_output.cxx b/Tests/CompileCommandOutput/compile_command_output.cxx new file mode 100644 index 0000000..9487c89 --- /dev/null +++ b/Tests/CompileCommandOutput/compile_command_output.cxx @@ -0,0 +1,9 @@ +#include "file with spaces.h" +#include "relative.h" + +int main (int argc, char** argv) +{ + file_with_spaces(); + relative(); + return 0; +} diff --git a/Tests/CompileCommandOutput/file with spaces.cxx b/Tests/CompileCommandOutput/file with spaces.cxx new file mode 100644 index 0000000..5759319 --- /dev/null +++ b/Tests/CompileCommandOutput/file with spaces.cxx @@ -0,0 +1,3 @@ +#include "file with spaces.h" + +void file_with_spaces() {} diff --git a/Tests/CompileCommandOutput/file with spaces.h b/Tests/CompileCommandOutput/file with spaces.h new file mode 100644 index 0000000..49b686c --- /dev/null +++ b/Tests/CompileCommandOutput/file with spaces.h @@ -0,0 +1 @@ +void file_with_spaces(); diff --git a/Tests/CompileCommandOutput/relative.cxx b/Tests/CompileCommandOutput/relative.cxx new file mode 100644 index 0000000..eae11e2 --- /dev/null +++ b/Tests/CompileCommandOutput/relative.cxx @@ -0,0 +1,3 @@ +#include "relative.h" + +void relative() {} diff --git a/Tests/CompileCommandOutput/relative.h b/Tests/CompileCommandOutput/relative.h new file mode 100644 index 0000000..2168035 --- /dev/null +++ b/Tests/CompileCommandOutput/relative.h @@ -0,0 +1 @@ +void relative(); |