On Mon, Apr 4, 2011 at 8:26 AM, Brad King <brad.k...@kitware.com> wrote:
> On 04/01/2011 02:42 PM, Manuel Klimek wrote:
>> sorry for the delay, but I was busy with other stuff - please find
>> attached a proposal patch for the test - I don't know enough about the
>> cmake testing infrastructure to say whether that was what you
>> imagined, please let me know if I should change anything.
>
> That looks pretty good, thanks.  Here are a few comments from review:
>
> - The cmSystemTools::ParseArguments method is not very solid.  It fails for
>  double-quotes in the middle of an argument, like '-I"a b"'.  Use the newer
>  ParseUnixCommandLine instead.  Unfortunately for historical reasons we
>  need to convert from vector<std::string> to vector<cmStdString>.  Try
>  the patch below.

Done.

> - The Source directory should not be touched for this.  Put the source code
>  in Tests/CMakeLib and move the code to build the executable to the
>  CMakeLists.txt file in that directory.

Done.

> - In the CompileCommandOutput test source files, please actually create a
>  symbol in each library and call them from the main.  Otherwise some
>  toolchains will complain about empty object files.

Done.

> - The ADD_TEST_MACRO call will need to be conditioned to run only when the
>  exported compile lines will work.  I will take care of that for you when
>  the rest of the patch is ready.

I also have the previous patches ready (re-based with master). Let me
know how we'll go on about submitting all that.

Thanks,
/Manuel

>
> Thanks,
> -Brad
>
>
> diff --git a/Source/run_compile_commands.cxx b/Source/run_compile_commands.cxx
> index 0b248f7..82cedfb 100644
> --- a/Source/run_compile_commands.cxx
> +++ b/Source/run_compile_commands.cxx
> @@ -117,8 +117,9 @@ int main ()
>       it = parser.GetTranslationUnits().begin(),
>       end = parser.GetTranslationUnits().end(); it != end; ++it)
>     {
> -    std::vector<cmStdString> command =
> -        cmSystemTools::ParseArguments(it->at("command").c_str());
> +    std::vector<std::string> command1;
> +    cmSystemTools::ParseUnixCommandLine(it->at("command").c_str(), command1);
> +    std::vector<cmStdString> command(command1.begin(), command1.end());
>     if (!cmSystemTools::RunSingleCommand(
>             command, 0, 0, it->at("directory").c_str()))
>       {
>



-- 
Manuel Klimek (http://go/klimek)
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 6265f81..01eb84a 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -2018,6 +2018,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();
_______________________________________________
cmake-developers mailing list
cmake-developers@cmake.org
http://public.kitware.com/cgi-bin/mailman/listinfo/cmake-developers

Reply via email to