Commit 0e6b05fc authored by Manuel Klimek's avatar Manuel Klimek Committed by Brad King

Adds a test for the compile command line output.

parent 5674844d
......@@ -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)
#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;
}
......@@ -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)
# 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)
#include "file with spaces.h"
#include "relative.h"
int main (int argc, char** argv)
{
file_with_spaces();
relative();
return 0;
}
#include "file with spaces.h"
void file_with_spaces() {}
#include "relative.h"
void relative() {}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment