Adds a test for the compile command line output.
This commit is contained in:
parent
5674844de4
commit
0e6b05fcba
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
|
@ -0,0 +1,9 @@
|
|||
#include "file with spaces.h"
|
||||
#include "relative.h"
|
||||
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
file_with_spaces();
|
||||
relative();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
#include "file with spaces.h"
|
||||
|
||||
void file_with_spaces() {}
|
|
@ -0,0 +1 @@
|
|||
void file_with_spaces();
|
|
@ -0,0 +1,3 @@
|
|||
#include "relative.h"
|
||||
|
||||
void relative() {}
|
|
@ -0,0 +1 @@
|
|||
void relative();
|
Loading…
Reference in New Issue