diff options
Diffstat (limited to 'Tests/CMakeLib')
-rw-r--r-- | Tests/CMakeLib/CMakeLists.txt | 39 | ||||
-rw-r--r-- | Tests/CMakeLib/run_compile_commands.cxx | 141 | ||||
-rw-r--r-- | Tests/CMakeLib/testGeneratedFileStream.cxx | 100 | ||||
-rw-r--r-- | Tests/CMakeLib/testSystemTools.cxx | 33 | ||||
-rw-r--r-- | Tests/CMakeLib/testUTF8.cxx | 125 | ||||
-rw-r--r-- | Tests/CMakeLib/testXMLParser.cxx | 17 | ||||
-rw-r--r-- | Tests/CMakeLib/testXMLParser.h.in | 6 | ||||
-rw-r--r-- | Tests/CMakeLib/testXMLParser.xml | 4 | ||||
-rw-r--r-- | Tests/CMakeLib/testXMLSafe.cxx | 47 |
9 files changed, 512 insertions, 0 deletions
diff --git a/Tests/CMakeLib/CMakeLists.txt b/Tests/CMakeLib/CMakeLists.txt new file mode 100644 index 000000000..4e819f470 --- /dev/null +++ b/Tests/CMakeLib/CMakeLists.txt @@ -0,0 +1,39 @@ +include_directories( + ${CMAKE_CURRENT_BINARY_DIR} + ${CMake_BINARY_DIR}/Source + ${CMake_SOURCE_DIR}/Source + ) + +set(CMakeLib_TESTS + testGeneratedFileStream + testSystemTools + testUTF8 + testXMLParser + testXMLSafe + ) + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/testXMLParser.h.in + ${CMAKE_CURRENT_BINARY_DIR}/testXMLParser.h @ONLY) + +create_test_sourcelist(CMakeLib_TEST_SRCS CMakeLibTests.cxx ${CMakeLib_TESTS}) +add_executable(CMakeLibTests ${CMakeLib_TEST_SRCS}) +target_link_libraries(CMakeLibTests CMakeLib) + +# Xcode 2.x forgets to create the output directory before linking +# the individual architectures. +if(CMAKE_OSX_ARCHITECTURES AND XCODE + AND NOT "${XCODE_VERSION}" MATCHES "^[^12]") + add_custom_command( + TARGET CMakeLibTests + PRE_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CFG_INTDIR}" + ) +endif() + +foreach(test ${CMakeLib_TESTS}) + add_test(CMakeLib.${test} CMakeLibTests ${test}) +endforeach() + +if(TEST_CompileCommandOutput) + add_executable(runcompilecommands run_compile_commands.cxx) + target_link_libraries(runcompilecommands CMakeLib) +endif() diff --git a/Tests/CMakeLib/run_compile_commands.cxx b/Tests/CMakeLib/run_compile_commands.cxx new file mode 100644 index 000000000..dc1ce24f7 --- /dev/null +++ b/Tests/CMakeLib/run_compile_commands.cxx @@ -0,0 +1,141 @@ +#include "cmSystemTools.h" + +class CompileCommandParser { +public: + class CommandType: public std::map<cmStdString, cmStdString> + { + public: + cmStdString const& at(cmStdString const& k) const + { + const_iterator i = this->find(k); + if(i != this->end()) { return i->second; } + static cmStdString emptyString; + return emptyString; + } + }; + 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\n"); + 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 = ""; + if(!Expect('"')) return; + while (!Expect('"')) + { + Expect('\\'); + this->String.append(1,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 = char(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<cmStdString> command; + cmSystemTools::ParseUnixCommandLine(it->at("command").c_str(), command); + 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/CMakeLib/testGeneratedFileStream.cxx b/Tests/CMakeLib/testGeneratedFileStream.cxx new file mode 100644 index 000000000..f8ca4af94 --- /dev/null +++ b/Tests/CMakeLib/testGeneratedFileStream.cxx @@ -0,0 +1,100 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2011 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmGeneratedFileStream.h" +#include "cmSystemTools.h" + +#define cmFailed(m1, m2) \ + std::cout << "FAILED: " << m1 << m2 << "\n"; failed=1 + +int testGeneratedFileStream(int, char*[]) +{ + int failed = 0; + cmGeneratedFileStream gm; + std::string file1 = "generatedFile1"; + std::string file2 = "generatedFile2"; + std::string file3 = "generatedFile3"; + std::string file4 = "generatedFile4"; + std::string file1tmp = file1 + ".tmp"; + std::string file2tmp = file2 + ".tmp"; + std::string file3tmp = file3 + ".tmp"; + std::string file4tmp = file4 + ".tmp"; + gm.Open(file1.c_str()); + gm << "This is generated file 1"; + gm.Close(); + gm.Open(file2.c_str()); + gm << "This is generated file 2"; + gm.Close(); + gm.Open(file3.c_str()); + gm << "This is generated file 3"; + gm.Close(); + gm.Open(file4.c_str()); + gm << "This is generated file 4"; + gm.Close(); + if ( cmSystemTools::FileExists(file1.c_str()) ) + { + if ( cmSystemTools::FileExists(file2.c_str()) ) + { + if ( cmSystemTools::FileExists(file3.c_str()) ) + { + if ( cmSystemTools::FileExists(file4.c_str()) ) + { + if ( cmSystemTools::FileExists(file1tmp.c_str()) ) + { + cmFailed("Something wrong with cmGeneratedFileStream. Temporary file is still here: ", file1tmp.c_str()); + } + else if ( cmSystemTools::FileExists(file2tmp.c_str()) ) + { + cmFailed("Something wrong with cmGeneratedFileStream. Temporary file is still here: ", file2tmp.c_str()); + } + else if ( cmSystemTools::FileExists(file3tmp.c_str()) ) + { + cmFailed("Something wrong with cmGeneratedFileStream. Temporary file is still here: ", file3tmp.c_str()); + } + else if ( cmSystemTools::FileExists(file4tmp.c_str()) ) + { + cmFailed("Something wrong with cmGeneratedFileStream. Temporary file is still here: ", file4tmp.c_str()); + } + else + { + std::cout << "cmGeneratedFileStream works\n"; + } + } + else + { + cmFailed("Something wrong with cmGeneratedFileStream. Cannot find file: ", file4.c_str()); + } + } + else + { + cmFailed("Something wrong with cmGeneratedFileStream. Found file: ", file3.c_str()); + } + } + else + { + cmFailed("Something wrong with cmGeneratedFileStream. Cannot find file: ", file2.c_str()); + } + } + else + { + cmFailed("Something wrong with cmGeneratedFileStream. Cannot find file: ", file1.c_str()); + } + cmSystemTools::RemoveFile(file1.c_str()); + cmSystemTools::RemoveFile(file2.c_str()); + cmSystemTools::RemoveFile(file3.c_str()); + cmSystemTools::RemoveFile(file4.c_str()); + cmSystemTools::RemoveFile(file1tmp.c_str()); + cmSystemTools::RemoveFile(file2tmp.c_str()); + cmSystemTools::RemoveFile(file3tmp.c_str()); + cmSystemTools::RemoveFile(file4tmp.c_str()); + + return failed; +} diff --git a/Tests/CMakeLib/testSystemTools.cxx b/Tests/CMakeLib/testSystemTools.cxx new file mode 100644 index 000000000..9309ae332 --- /dev/null +++ b/Tests/CMakeLib/testSystemTools.cxx @@ -0,0 +1,33 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2011 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmSystemTools.h" + +#define cmPassed(m) std::cout << "Passed: " << m << "\n" +#define cmFailed(m) std::cout << "FAILED: " << m << "\n"; failed=1 + +int testSystemTools(int, char*[]) +{ + int failed = 0; + // ---------------------------------------------------------------------- + // Test cmSystemTools::UpperCase + std::string str = "abc"; + std::string strupper = "ABC"; + if(cmSystemTools::UpperCase(str) == strupper) + { + cmPassed("cmSystemTools::UpperCase is working"); + } + else + { + cmFailed("cmSystemTools::UpperCase is working"); + } + return failed; +} diff --git a/Tests/CMakeLib/testUTF8.cxx b/Tests/CMakeLib/testUTF8.cxx new file mode 100644 index 000000000..4ab96cf01 --- /dev/null +++ b/Tests/CMakeLib/testUTF8.cxx @@ -0,0 +1,125 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include <cm_utf8.h> + +#include <string.h> +#include <stdio.h> + +typedef char test_utf8_char[5]; + +static void test_utf8_char_print(test_utf8_char const c) +{ + unsigned char const* d = reinterpret_cast<unsigned char const*>(c); + printf("[0x%02X,0x%02X,0x%02X,0x%02X]", + (int)d[0], (int)d[1], (int)d[2], (int)d[3]); +} + +struct test_utf8_entry +{ + int n; + test_utf8_char str; + unsigned int chr; +}; + +static test_utf8_entry const good_entry[] = { + {1, "\x20\x00\x00\x00", 0x0020}, /* Space. */ + {2, "\xC2\xA9\x00\x00", 0x00A9}, /* Copyright. */ + {3, "\xE2\x80\x98\x00", 0x2018}, /* Open-single-quote. */ + {3, "\xE2\x80\x99\x00", 0x2019}, /* Close-single-quote. */ + {4, "\xF0\xA3\x8E\xB4", 0x233B4}, /* Example from RFC 3629. */ + {0, {0,0,0,0,0}, 0} +}; + +static test_utf8_char const bad_chars[] = { + "\x80\x00\x00\x00", + "\xC0\x00\x00\x00", + "\xE0\x00\x00\x00", + "\xE0\x80\x80\x00", + "\xF0\x80\x80\x80", + {0,0,0,0,0} +}; + +static void report_good(bool passed, test_utf8_char const c) +{ + printf("%s: decoding good ", passed?"pass":"FAIL"); + test_utf8_char_print(c); + printf(" (%s) ", c); +} + +static void report_bad(bool passed, test_utf8_char const c) +{ + printf("%s: decoding bad ", passed?"pass":"FAIL"); + test_utf8_char_print(c); + printf(" "); +} + +static bool decode_good(test_utf8_entry const entry) +{ + unsigned int uc; + if(const char* e = cm_utf8_decode_character(entry.str, entry.str+4, &uc)) + { + int used = static_cast<int>(e-entry.str); + if(uc != entry.chr) + { + report_good(false, entry.str); + printf("expected 0x%04X, got 0x%04X\n", entry.chr, uc); + return false; + } + if(used != entry.n) + { + report_good(false, entry.str); + printf("had %d bytes, used %d\n", entry.n, used); + return false; + } + report_good(true, entry.str); + printf("got 0x%04X\n", uc); + return true; + } + report_good(false, entry.str); + printf("failed\n"); + return false; +} + +static bool decode_bad(test_utf8_char const s) +{ + unsigned int uc = 0xFFFFu; + const char* e = cm_utf8_decode_character(s, s+4, &uc); + if(e) + { + report_bad(false, s); + printf("expected failure, got 0x%04X\n", uc); + return false; + } + report_bad(true, s); + printf("failed as expected\n"); + return true; +} + +int testUTF8(int, char*[]) +{ + int result = 0; + for(test_utf8_entry const* e = good_entry; e->n; ++e) + { + if(!decode_good(*e)) + { + result = 1; + } + } + for(test_utf8_char const* c = bad_chars; (*c)[0]; ++c) + { + if(!decode_bad(*c)) + { + result = 1; + } + } + return result; +} diff --git a/Tests/CMakeLib/testXMLParser.cxx b/Tests/CMakeLib/testXMLParser.cxx new file mode 100644 index 000000000..54ed5dc90 --- /dev/null +++ b/Tests/CMakeLib/testXMLParser.cxx @@ -0,0 +1,17 @@ +#include "testXMLParser.h" + +#include "cmXMLParser.h" + +#include <cmsys/ios/iostream> + +int testXMLParser(int, char*[]) +{ + // TODO: Derive from parser and check attributes. + cmXMLParser parser; + if(!parser.ParseFile(SOURCE_DIR "/testXMLParser.xml")) + { + cmsys_ios::cerr << "cmXMLParser failed!" << cmsys_ios::endl; + return 1; + } + return 0; +} diff --git a/Tests/CMakeLib/testXMLParser.h.in b/Tests/CMakeLib/testXMLParser.h.in new file mode 100644 index 000000000..da0b2757b --- /dev/null +++ b/Tests/CMakeLib/testXMLParser.h.in @@ -0,0 +1,6 @@ +#ifndef testXMLParser_h +#define testXMLParser_h + +#define SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@" + +#endif diff --git a/Tests/CMakeLib/testXMLParser.xml b/Tests/CMakeLib/testXMLParser.xml new file mode 100644 index 000000000..5a13f070a --- /dev/null +++ b/Tests/CMakeLib/testXMLParser.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Document> + <Element attr="1"/> +</Document> diff --git a/Tests/CMakeLib/testXMLSafe.cxx b/Tests/CMakeLib/testXMLSafe.cxx new file mode 100644 index 000000000..60442fab7 --- /dev/null +++ b/Tests/CMakeLib/testXMLSafe.cxx @@ -0,0 +1,47 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include <cmXMLSafe.h> + +#include "cmStandardIncludes.h" + +struct test_pair +{ + const char* in; + const char* out; +}; + +static test_pair const pairs[] = { + {"copyright \xC2\xA9", "copyright \xC2\xA9"}, + {"form-feed \f", "form-feed [NON-XML-CHAR-0xC]"}, + {"angles <>", "angles <>"}, + {"ampersand &", "ampersand &"}, + {"bad-byte \x80", "bad-byte [NON-UTF-8-BYTE-0x80]"}, + {0,0} +}; + +int testXMLSafe(int, char*[]) +{ + int result = 0; + for(test_pair const* p = pairs; p->in; ++p) + { + cmXMLSafe xs(p->in); + cmOStringStream oss; + oss << xs; + std::string out = oss.str(); + if(out != p->out) + { + printf("expected [%s], got [%s]\n", p->out, out.c_str()); + result = 1; + } + } + return result; +} |