cmUseMangledMesaCommand.cxx 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing for details. */
  3. #include "cmUseMangledMesaCommand.h"
  4. #include "cmSystemTools.h"
  5. #include <cmsys/FStream.hxx>
  6. #include <cmsys/RegularExpression.hxx>
  7. bool cmUseMangledMesaCommand::InitialPass(std::vector<std::string> const& args,
  8. cmExecutionStatus&)
  9. {
  10. if (this->Disallowed(
  11. cmPolicies::CMP0030,
  12. "The use_mangled_mesa command should not be called; see CMP0030.")) {
  13. return true;
  14. }
  15. // expected two arguments:
  16. // arguement one: the full path to gl_mangle.h
  17. // arguement two : directory for output of edited headers
  18. if (args.size() != 2) {
  19. this->SetError("called with incorrect number of arguments");
  20. return false;
  21. }
  22. const char* inputDir = args[0].c_str();
  23. std::string glh = inputDir;
  24. glh += "/";
  25. glh += "gl.h";
  26. if (!cmSystemTools::FileExists(glh.c_str())) {
  27. std::string e = "Bad path to Mesa, could not find: ";
  28. e += glh;
  29. e += " ";
  30. this->SetError(e);
  31. return false;
  32. }
  33. const char* destDir = args[1].c_str();
  34. std::vector<std::string> files;
  35. cmSystemTools::Glob(inputDir, "\\.h$", files);
  36. if (files.empty()) {
  37. cmSystemTools::Error("Could not open Mesa Directory ", inputDir);
  38. return false;
  39. }
  40. cmSystemTools::MakeDirectory(destDir);
  41. for (std::vector<std::string>::iterator i = files.begin(); i != files.end();
  42. ++i) {
  43. std::string path = inputDir;
  44. path += "/";
  45. path += *i;
  46. this->CopyAndFullPathMesaHeader(path.c_str(), destDir);
  47. }
  48. return true;
  49. }
  50. void cmUseMangledMesaCommand::CopyAndFullPathMesaHeader(const char* source,
  51. const char* outdir)
  52. {
  53. std::string dir, file;
  54. cmSystemTools::SplitProgramPath(source, dir, file);
  55. std::string outFile = outdir;
  56. outFile += "/";
  57. outFile += file;
  58. std::string tempOutputFile = outFile;
  59. tempOutputFile += ".tmp";
  60. cmsys::ofstream fout(tempOutputFile.c_str());
  61. if (!fout) {
  62. cmSystemTools::Error("Could not open file for write in copy operation: ",
  63. tempOutputFile.c_str(), outdir);
  64. cmSystemTools::ReportLastSystemError("");
  65. return;
  66. }
  67. cmsys::ifstream fin(source);
  68. if (!fin) {
  69. cmSystemTools::Error("Could not open file for read in copy operation",
  70. source);
  71. return;
  72. }
  73. // now copy input to output and expand variables in the
  74. // input file at the same time
  75. std::string inLine;
  76. // regular expression for any #include line
  77. cmsys::RegularExpression includeLine(
  78. "^[ \t]*#[ \t]*include[ \t]*[<\"]([^\">]+)[\">]");
  79. // regular expression for gl/ or GL/ in a file (match(1) of above)
  80. cmsys::RegularExpression glDirLine("(gl|GL)(/|\\\\)([^<\"]+)");
  81. // regular expression for gl GL or xmesa in a file (match(1) of above)
  82. cmsys::RegularExpression glLine("(gl|GL|xmesa)");
  83. while (cmSystemTools::GetLineFromStream(fin, inLine)) {
  84. if (includeLine.find(inLine.c_str())) {
  85. std::string includeFile = includeLine.match(1);
  86. if (glDirLine.find(includeFile.c_str())) {
  87. std::string gfile = glDirLine.match(3);
  88. fout << "#include \"" << outdir << "/" << gfile << "\"\n";
  89. } else if (glLine.find(includeFile.c_str())) {
  90. fout << "#include \"" << outdir << "/" << includeLine.match(1)
  91. << "\"\n";
  92. } else {
  93. fout << inLine << "\n";
  94. }
  95. } else {
  96. fout << inLine << "\n";
  97. }
  98. }
  99. // close the files before attempting to copy
  100. fin.close();
  101. fout.close();
  102. cmSystemTools::CopyFileIfDifferent(tempOutputFile.c_str(), outFile.c_str());
  103. cmSystemTools::RemoveFile(tempOutputFile.c_str());
  104. }