testGccDepfileReader.cxx 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. #include <cstddef> // IWYU pragma: keep
  2. #include <iostream>
  3. #include <memory>
  4. #include <string>
  5. #include <utility>
  6. #include <vector>
  7. #include "cmsys/FStream.hxx"
  8. #include "cmGccDepfileReader.h"
  9. #include "cmGccDepfileReaderTypes.h" // for cmGccDepfileContent, cmGccStyle...
  10. #include "cmSystemTools.h"
  11. namespace {
  12. cmGccDepfileContent readPlainDepfile(const char* filePath)
  13. {
  14. cmGccDepfileContent result;
  15. cmsys::ifstream is(filePath);
  16. if (!is.is_open())
  17. return result;
  18. std::string line;
  19. cmGccStyleDependency dep;
  20. bool readingRules = true;
  21. while (cmSystemTools::GetLineFromStream(is, line)) {
  22. if (line == "--RULES--") {
  23. if (!dep.rules.empty()) {
  24. result.push_back(std::move(dep));
  25. dep = cmGccStyleDependency();
  26. }
  27. readingRules = true;
  28. } else if (line == "--DEPENDENCIES--") {
  29. readingRules = false;
  30. } else {
  31. std::vector<std::string>& dst = readingRules ? dep.rules : dep.paths;
  32. dst.push_back(std::move(line));
  33. line = std::string();
  34. }
  35. }
  36. if (!dep.rules.empty()) {
  37. result.push_back(std::move(dep));
  38. }
  39. return result;
  40. }
  41. bool compare(const std::vector<std::string>& actual,
  42. const std::vector<std::string>& expected, const char* msg)
  43. {
  44. if (actual.size() != expected.size()) {
  45. std::cerr << msg << "expected " << expected.size() << " entries."
  46. << std::endl
  47. << "Actual number of entries: " << actual.size() << std::endl;
  48. return false;
  49. }
  50. for (std::size_t i = 0; i < actual.size(); ++i) {
  51. if (actual[i] != expected[i]) {
  52. std::cerr << msg << std::endl
  53. << "expected: " << expected[i] << std::endl
  54. << "actual: " << actual[i] << std::endl;
  55. return false;
  56. }
  57. }
  58. return true;
  59. }
  60. bool compare(const cmGccDepfileContent& actual,
  61. const cmGccDepfileContent& expected)
  62. {
  63. if (actual.size() != expected.size()) {
  64. std::cerr << "Expected " << expected.size() << " entries." << std::endl
  65. << "Actual number of entries: " << actual.size() << std::endl;
  66. return false;
  67. }
  68. for (std::size_t i = 0; i < actual.size(); ++i) {
  69. if (!compare(actual[i].rules, expected[i].rules, "Rules differ: ") ||
  70. !compare(actual[i].paths, expected[i].paths, "Paths differ: ")) {
  71. return false;
  72. }
  73. }
  74. return true;
  75. }
  76. void dump(const char* label, const cmGccDepfileContent& dfc)
  77. {
  78. std::cerr << label << std::endl;
  79. for (const auto& entry : dfc) {
  80. auto rit = entry.rules.cbegin();
  81. if (rit != entry.rules.cend()) {
  82. std::cerr << *rit;
  83. for (++rit; rit != entry.rules.cend(); ++rit) {
  84. std::cerr << " " << *rit;
  85. }
  86. std::cerr << ": " << std::endl;
  87. }
  88. for (const auto& path : entry.paths) {
  89. std::cerr << " " << path << std::endl;
  90. }
  91. }
  92. }
  93. } // anonymous namespace
  94. int testGccDepfileReader(int argc, char* argv[])
  95. {
  96. if (argc < 2) {
  97. std::cout << "Invalid arguments.\n";
  98. return -1;
  99. }
  100. std::string dataDirPath = argv[1];
  101. dataDirPath += "/testGccDepfileReader_data";
  102. const int numberOfTestFiles = 3;
  103. for (int i = 1; i <= numberOfTestFiles; ++i) {
  104. const std::string base = dataDirPath + "/deps" + std::to_string(i);
  105. const std::string depfile = base + ".d";
  106. const std::string plainDepfile = base + ".txt";
  107. std::cout << "Comparing " << base << " with " << plainDepfile << std::endl;
  108. const auto actual = cmReadGccDepfile(depfile.c_str());
  109. const auto expected = readPlainDepfile(plainDepfile.c_str());
  110. if (!compare(actual, expected)) {
  111. dump("actual", actual);
  112. dump("expected", expected);
  113. return 1;
  114. }
  115. }
  116. return 0;
  117. }