summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManuel Klimek <klimek@google.com>2011-03-31 23:55:00 (GMT)
committerBrad King <brad.king@kitware.com>2011-04-25 17:27:59 (GMT)
commit0e6b05fcba61a1b113b841dd2b3e1e5060866d0e (patch)
tree7c7a2237420f7c6692e7d9d752373d1ceb4ef7cb
parent5674844de4b74d0b66cfc6b8237e631702c43637 (diff)
downloadCMake-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.txt3
-rw-r--r--Tests/CMakeLib/run_compile_commands.cxx132
-rw-r--r--Tests/CMakeLists.txt3
-rw-r--r--Tests/CompileCommandOutput/CMakeLists.txt11
-rw-r--r--Tests/CompileCommandOutput/compile_command_output.cxx9
-rw-r--r--Tests/CompileCommandOutput/file with spaces.cxx3
-rw-r--r--Tests/CompileCommandOutput/file with spaces.h1
-rw-r--r--Tests/CompileCommandOutput/relative.cxx3
-rw-r--r--Tests/CompileCommandOutput/relative.h1
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();