diff options
author | Joerg Bornemann <joerg.bornemann@qt.io> | 2020-01-21 09:26:42 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2020-01-28 16:16:11 (GMT) |
commit | f8c505d4b30aa636b013486913591060b2040716 (patch) | |
tree | 2853577d4c09ff8f11dac45bfd4ba8a2a014dc90 /Tests | |
parent | 306328ace87376dddb2a42bf33c6338aac5d09ad (diff) | |
download | CMake-f8c505d4b30aa636b013486913591060b2040716.zip CMake-f8c505d4b30aa636b013486913591060b2040716.tar.gz CMake-f8c505d4b30aa636b013486913591060b2040716.tar.bz2 |
Add a parser for GCC-style depfiles
Introduce the function cmReadGccDepfile that parses a GCC-style depfile
and returns its content. The implementation uses a lexer that is
modeled after the re2c implementation in Ninja.
The sample files of the autotest have been created with gcc 8.3.0.
This depfile reader is to be used by the Autogen facility to make use
of the depfiles that are generated by Qt's meta object compiler.
Diffstat (limited to 'Tests')
-rw-r--r-- | Tests/CMakeLib/CMakeLists.txt | 2 | ||||
-rw-r--r-- | Tests/CMakeLib/testGccDepfileReader.cxx | 131 | ||||
-rw-r--r-- | Tests/CMakeLib/testGccDepfileReader_data/deps1.d | 20 | ||||
-rw-r--r-- | Tests/CMakeLib/testGccDepfileReader_data/deps1.txt | 26 | ||||
-rw-r--r-- | Tests/CMakeLib/testGccDepfileReader_data/deps2.d | 1 | ||||
-rw-r--r-- | Tests/CMakeLib/testGccDepfileReader_data/deps2.txt | 5 | ||||
-rw-r--r-- | Tests/CMakeLib/testGccDepfileReader_data/deps3.d | 2 | ||||
-rw-r--r-- | Tests/CMakeLib/testGccDepfileReader_data/deps3.txt | 11 |
8 files changed, 198 insertions, 0 deletions
diff --git a/Tests/CMakeLib/CMakeLists.txt b/Tests/CMakeLib/CMakeLists.txt index 25d2de6..bb50d76 100644 --- a/Tests/CMakeLib/CMakeLists.txt +++ b/Tests/CMakeLib/CMakeLists.txt @@ -11,6 +11,7 @@ set(CMakeLib_TESTS testCTestResourceAllocator.cxx testCTestResourceSpec.cxx testCTestResourceGroups.cxx + testGccDepfileReader.cxx testGeneratedFileStream.cxx testRST.cxx testRange.cxx @@ -35,6 +36,7 @@ set(testRST_ARGS ${CMAKE_CURRENT_SOURCE_DIR}) set(testUVProcessChain_ARGS $<TARGET_FILE:testUVProcessChainHelper>) set(testUVStreambuf_ARGS $<TARGET_FILE:cmake>) set(testCTestResourceSpec_ARGS ${CMAKE_CURRENT_SOURCE_DIR}) +set(testGccDepfileReader_ARGS ${CMAKE_CURRENT_SOURCE_DIR}) if(WIN32) list(APPEND CMakeLib_TESTS diff --git a/Tests/CMakeLib/testGccDepfileReader.cxx b/Tests/CMakeLib/testGccDepfileReader.cxx new file mode 100644 index 0000000..924d87b --- /dev/null +++ b/Tests/CMakeLib/testGccDepfileReader.cxx @@ -0,0 +1,131 @@ +#include <cstddef> +#include <iostream> +#include <memory> +#include <string> +#include <utility> +#include <vector> + +#include "cmsys/FStream.hxx" + +#include "cmGccDepfileReader.h" +#include "cmGccDepfileReaderTypes.h" // for cmGccDepfileContent, cmGccStyle... +#include "cmSystemTools.h" + +namespace { + +cmGccDepfileContent readPlainDepfile(const char* filePath) +{ + cmGccDepfileContent result; + cmsys::ifstream is(filePath); + if (!is.is_open()) + return result; + std::string line; + + cmGccStyleDependency dep; + bool readingRules = true; + while (cmSystemTools::GetLineFromStream(is, line)) { + if (line == "--RULES--") { + if (!dep.rules.empty()) { + result.push_back(std::move(dep)); + dep = cmGccStyleDependency(); + } + readingRules = true; + } else if (line == "--DEPENDENCIES--") { + readingRules = false; + } else { + std::vector<std::string>& dst = readingRules ? dep.rules : dep.paths; + dst.push_back(std::move(line)); + line = std::string(); + } + } + + if (!dep.rules.empty()) { + result.push_back(std::move(dep)); + } + + return result; +} + +bool compare(const std::vector<std::string>& actual, + const std::vector<std::string>& expected, const char* msg) +{ + if (actual.size() != expected.size()) { + std::cerr << msg << "expected " << expected.size() << " entries." + << std::endl + << "Actual number of entries: " << actual.size() << std::endl; + return false; + } + for (std::size_t i = 0; i < actual.size(); ++i) { + if (actual[i] != expected[i]) { + std::cerr << msg << std::endl + << "expected: " << expected[i] << std::endl + << "actual: " << actual[i] << std::endl; + return false; + } + } + return true; +} + +bool compare(const cmGccDepfileContent& actual, + const cmGccDepfileContent& expected) +{ + if (actual.size() != expected.size()) { + std::cerr << "Expected " << expected.size() << " entries." << std::endl + << "Actual number of entries: " << actual.size() << std::endl; + return false; + } + for (std::size_t i = 0; i < actual.size(); ++i) { + if (!compare(actual[i].rules, expected[i].rules, "Rules differ: ") || + !compare(actual[i].paths, expected[i].paths, "Paths differ: ")) { + return false; + } + } + return true; +} + +void dump(const char* label, const cmGccDepfileContent& dfc) +{ + std::cerr << label << std::endl; + for (const auto& entry : dfc) { + auto rit = entry.rules.cbegin(); + if (rit != entry.rules.cend()) { + std::cerr << *rit; + for (++rit; rit != entry.rules.cend(); ++rit) { + std::cerr << " " << *rit; + } + std::cerr << ": " << std::endl; + } + for (const auto& path : entry.paths) { + std::cerr << " " << path << std::endl; + } + } +} + +} // anonymous namespace + +int testGccDepfileReader(int argc, char* argv[]) +{ + if (argc < 2) { + std::cout << "Invalid arguments.\n"; + return -1; + } + + std::string dataDirPath = argv[1]; + dataDirPath += "/testGccDepfileReader_data"; + const int numberOfTestFiles = 3; + for (int i = 1; i <= numberOfTestFiles; ++i) { + const std::string base = dataDirPath + "/deps" + std::to_string(i); + const std::string depfile = base + ".d"; + const std::string plainDepfile = base + ".txt"; + std::cout << "Comparing " << base << " with " << plainDepfile << std::endl; + const auto actual = cmReadGccDepfile(depfile.c_str()); + const auto expected = readPlainDepfile(plainDepfile.c_str()); + if (!compare(actual, expected)) { + dump("actual", actual); + dump("expected", expected); + return 1; + } + } + + return 0; +} diff --git a/Tests/CMakeLib/testGccDepfileReader_data/deps1.d b/Tests/CMakeLib/testGccDepfileReader_data/deps1.d new file mode 100644 index 0000000..9e34863 --- /dev/null +++ b/Tests/CMakeLib/testGccDepfileReader_data/deps1.d @@ -0,0 +1,20 @@ +main.o: main.cpp /usr/include/stdc-predef.h /usr/include/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h \ + /usr/lib/gcc/x86_64-linux-gnu/8/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/cookie_io_functions_t.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h diff --git a/Tests/CMakeLib/testGccDepfileReader_data/deps1.txt b/Tests/CMakeLib/testGccDepfileReader_data/deps1.txt new file mode 100644 index 0000000..fd2679f --- /dev/null +++ b/Tests/CMakeLib/testGccDepfileReader_data/deps1.txt @@ -0,0 +1,26 @@ +--RULES-- +main.o +--DEPENDENCIES-- +main.cpp +/usr/include/stdc-predef.h +/usr/include/stdio.h +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h +/usr/include/features.h +/usr/include/x86_64-linux-gnu/sys/cdefs.h +/usr/include/x86_64-linux-gnu/bits/wordsize.h +/usr/include/x86_64-linux-gnu/bits/long-double.h +/usr/include/x86_64-linux-gnu/gnu/stubs.h +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h +/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h +/usr/lib/gcc/x86_64-linux-gnu/8/include/stdarg.h +/usr/include/x86_64-linux-gnu/bits/types.h +/usr/include/x86_64-linux-gnu/bits/typesizes.h +/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h +/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h +/usr/include/x86_64-linux-gnu/bits/types/FILE.h +/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h +/usr/include/x86_64-linux-gnu/bits/types/cookie_io_functions_t.h +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h diff --git a/Tests/CMakeLib/testGccDepfileReader_data/deps2.d b/Tests/CMakeLib/testGccDepfileReader_data/deps2.d new file mode 100644 index 0000000..25f0d78 --- /dev/null +++ b/Tests/CMakeLib/testGccDepfileReader_data/deps2.d @@ -0,0 +1 @@ +foo.o bar.o: foobar.c diff --git a/Tests/CMakeLib/testGccDepfileReader_data/deps2.txt b/Tests/CMakeLib/testGccDepfileReader_data/deps2.txt new file mode 100644 index 0000000..afaf78e --- /dev/null +++ b/Tests/CMakeLib/testGccDepfileReader_data/deps2.txt @@ -0,0 +1,5 @@ +--RULES-- +foo.o +bar.o +--DEPENDENCIES-- +foobar.c diff --git a/Tests/CMakeLib/testGccDepfileReader_data/deps3.d b/Tests/CMakeLib/testGccDepfileReader_data/deps3.d new file mode 100644 index 0000000..d75ceed --- /dev/null +++ b/Tests/CMakeLib/testGccDepfileReader_data/deps3.d @@ -0,0 +1,2 @@ +main.o: main.cpp foo\#bar.h foo\\#bar.h foo\ bar.h \ + foo\\\ bar.h foo\\\\\ bar.h foo\\\\ foo$$bar.h diff --git a/Tests/CMakeLib/testGccDepfileReader_data/deps3.txt b/Tests/CMakeLib/testGccDepfileReader_data/deps3.txt new file mode 100644 index 0000000..448f69c --- /dev/null +++ b/Tests/CMakeLib/testGccDepfileReader_data/deps3.txt @@ -0,0 +1,11 @@ +--RULES-- +main.o +--DEPENDENCIES-- +main.cpp +foo#bar.h +foo\#bar.h +foo bar.h +foo\ bar.h +foo\\ bar.h +foo\\\\ +foo$bar.h |