Advertisement
Guest User

Untitled

a guest
Jan 25th, 2020
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.51 KB | None | 0 0
  1. #include <iostream>
  2. #include <fstream>
  3. #include <string>
  4. #include <vector>
  5.  
  6. struct CompileState
  7. {
  8.     enum class Section { none, files, warnings };
  9.     Section section = none;
  10.  
  11.     std::vector<std::string> files, arguments;
  12.     std::string filestr;
  13.  
  14.     std::string output;
  15.  
  16.     struct Version
  17.     {
  18.         std::string str;
  19.         int num = 0;
  20.         operator bool() const { return num == 0; }
  21.     } version;
  22. }
  23.  
  24. void compileFile(std::string fileName);
  25. bool startWith(const std::string& s, const std::string& sub) { return s.find(sub) == 0; }
  26. void compileCommand(const std::string& command, CompileState& state)
  27.  
  28. #define COMPILER "g++" // TODO support more compilers, at least clang if not MSVC
  29.  
  30. // https://stackoverflow.com/questions/20986144/how-to-concatenate-strings-with-space-into-one-string-with-stl-in-c
  31. auto tostr = [](auto vec) { std::accumulate(std::begin(vec) + 1, std::end(vec), vec[0],
  32.         [](const auto& s0, const auto& s1) { return s0 += " " + s1; });
  33. };
  34.  
  35. int main(int argc, char *argv[])
  36. {
  37.     if (argc == 0)
  38.     {
  39.         std::cout << "Enter a command file!\n";
  40.         return 1;
  41.     }
  42.  
  43.     std::string allCommand;
  44.  
  45.     for (int i = 0; i < argc; i++) // C++20 range
  46.     {
  47.         auto info = compileFile(argv[i]);
  48.         allCommand += info.filestr + tostr(info.arguments);
  49.         std::cout << "Executing:\t" << allCommand << endl;
  50.         //system(allCommand); // TODO don't system random shit from users...
  51.     }
  52. }
  53.  
  54. CompileState compileFile(std::string fileName)
  55. {
  56.     ifstream file{fileName};
  57.     CompileState state;
  58.     for (std::string c; getline(file, c); ) compileCommand(c, state);
  59.  
  60.     state.filestr = tostr(state.files);
  61.     if(state.version) state.filestr += " -std=" + state.version.str;
  62.     if(state.output) state.arguments.push_back("-o " + state.output);
  63.     return state;
  64. }
  65.  
  66. void compileCommand(const string& command, CompileState& state)
  67. {
  68.     if(command[0] == '-') state.section = Section::none;
  69.  
  70.          if (command == "-FILES" || command == "-F")    state.section = Section::files;
  71.     else if (command == "-WARNINGS" || command == "-W") state.section = Section::warnings;
  72.     else if (command == "-DEFAULT_WARNINGS")            state.arguments.append("-Wall -Wextra -Wpedantic");
  73.     else if (startWith(command, "-VERSION=") || startWith(command,"-V=")
  74.     {
  75.         auto sep = command.find('=');
  76.         auto vers = command.substr(sep+1);
  77.         try {
  78.             int ver = stoi(vers);
  79.             if(state.version) { std::log << "Multiple VERSIONs set, overwriting "
  80.                 << state.version << " with " << vers << "\n"; }
  81.             state.version = {ver, vers};
  82.         } catch(...) {
  83.             std::log << "Invalid version provided '" << vers << "'\n";
  84.         }
  85.     }
  86.     else if (startWith(command, "-OUTPUT=") || startWith(command, "-O="))
  87.     {
  88.         sub = command.substr(command.find("=")+1);
  89.         if(!state.output.empty()) std::log << "Multiple output commands! Overwriting '"
  90.             << state.output << "' with '" << sub << "'\n";
  91.         state.output = sub;
  92.     }
  93.     else if (state.section != Section::none)
  94.     {
  95.         switch(state.section)
  96.         {
  97.             case Section::files:
  98.                 files.push_back(command);
  99.                 break;
  100.             case Section::warnings:
  101.                 state.arguments.push_back("-W" + command);
  102.                 break;
  103.             case default:
  104.                 std::log << "Unknown command with no state opened: '" << command << "'\n";
  105.         }
  106.     }
  107. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement