1
0

run_compile_commands.cxx 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. #include "cmSystemTools.h"
  2. #include <cmsys/FStream.hxx>
  3. #include <iostream>
  4. #include <map>
  5. #include <stdlib.h>
  6. #include <string>
  7. #include <utility>
  8. #include <vector>
  9. class CompileCommandParser
  10. {
  11. public:
  12. class CommandType : public std::map<std::string, std::string>
  13. {
  14. public:
  15. std::string const& at(std::string const& k) const
  16. {
  17. const_iterator i = this->find(k);
  18. if (i != this->end()) {
  19. return i->second;
  20. }
  21. static std::string emptyString;
  22. return emptyString;
  23. }
  24. };
  25. typedef std::vector<CommandType> TranslationUnitsType;
  26. CompileCommandParser(std::istream& input)
  27. : Input(input)
  28. {
  29. }
  30. void Parse()
  31. {
  32. NextNonWhitespace();
  33. ParseTranslationUnits();
  34. }
  35. const TranslationUnitsType& GetTranslationUnits()
  36. {
  37. return this->TranslationUnits;
  38. }
  39. private:
  40. void ParseTranslationUnits()
  41. {
  42. this->TranslationUnits = TranslationUnitsType();
  43. ExpectOrDie('[', "at start of compile command file\n");
  44. do {
  45. ParseTranslationUnit();
  46. this->TranslationUnits.push_back(this->Command);
  47. } while (Expect(','));
  48. ExpectOrDie(']', "at end of array");
  49. }
  50. void ParseTranslationUnit()
  51. {
  52. this->Command = CommandType();
  53. if (!Expect('{')) {
  54. return;
  55. }
  56. if (Expect('}')) {
  57. return;
  58. }
  59. do {
  60. ParseString();
  61. std::string name = this->String;
  62. ExpectOrDie(':', "between name and value");
  63. ParseString();
  64. std::string value = this->String;
  65. this->Command[name] = value;
  66. } while (Expect(','));
  67. ExpectOrDie('}', "at end of object");
  68. }
  69. void ParseString()
  70. {
  71. this->String = "";
  72. if (!Expect('"')) {
  73. return;
  74. }
  75. while (!Expect('"')) {
  76. Expect('\\');
  77. this->String.append(1, C);
  78. Next();
  79. }
  80. }
  81. bool Expect(char c)
  82. {
  83. if (this->C == c) {
  84. NextNonWhitespace();
  85. return true;
  86. }
  87. return false;
  88. }
  89. void ExpectOrDie(char c, const std::string& message)
  90. {
  91. if (!Expect(c)) {
  92. ErrorExit(std::string("'") + c + "' expected " + message + ".");
  93. }
  94. }
  95. void NextNonWhitespace()
  96. {
  97. do {
  98. Next();
  99. } while (IsWhitespace());
  100. }
  101. void Next()
  102. {
  103. this->C = char(Input.get());
  104. if (this->Input.bad()) {
  105. ErrorExit("Unexpected end of file.");
  106. }
  107. }
  108. void ErrorExit(const std::string& message)
  109. {
  110. std::cout << "ERROR: " << message;
  111. exit(1);
  112. }
  113. bool IsWhitespace()
  114. {
  115. return (this->C == ' ' || this->C == '\t' || this->C == '\n' ||
  116. this->C == '\r');
  117. }
  118. char C;
  119. TranslationUnitsType TranslationUnits;
  120. CommandType Command;
  121. std::string String;
  122. std::istream& Input;
  123. };
  124. int main()
  125. {
  126. cmsys::ifstream file("compile_commands.json");
  127. CompileCommandParser parser(file);
  128. parser.Parse();
  129. for (CompileCommandParser::TranslationUnitsType::const_iterator
  130. it = parser.GetTranslationUnits().begin(),
  131. end = parser.GetTranslationUnits().end();
  132. it != end; ++it) {
  133. std::vector<std::string> command;
  134. cmSystemTools::ParseUnixCommandLine(it->at("command").c_str(), command);
  135. if (!cmSystemTools::RunSingleCommand(command, CM_NULLPTR, CM_NULLPTR,
  136. CM_NULLPTR,
  137. it->at("directory").c_str())) {
  138. std::cout << "ERROR: Failed to run command \"" << command[0] << "\""
  139. << std::endl;
  140. exit(1);
  141. }
  142. }
  143. return 0;
  144. }