Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <fstream>
- #include <string>
- #include <vector>
- struct CompileState
- {
- enum class Section { none, files, warnings };
- Section section = none;
- std::vector<std::string> files, arguments;
- std::string filestr;
- std::string output;
- struct Version
- {
- std::string str;
- int num = 0;
- operator bool() const { return num == 0; }
- } version;
- }
- void compileFile(std::string fileName);
- bool startWith(const std::string& s, const std::string& sub) { return s.find(sub) == 0; }
- void compileCommand(const std::string& command, CompileState& state)
- #define COMPILER "g++" // TODO support more compilers, at least clang if not MSVC
- // https://stackoverflow.com/questions/20986144/how-to-concatenate-strings-with-space-into-one-string-with-stl-in-c
- auto tostr = [](auto vec) { std::accumulate(std::begin(vec) + 1, std::end(vec), vec[0],
- [](const auto& s0, const auto& s1) { return s0 += " " + s1; });
- };
- int main(int argc, char *argv[])
- {
- if (argc == 0)
- {
- std::cout << "Enter a command file!\n";
- return 1;
- }
- std::string allCommand;
- for (int i = 0; i < argc; i++) // C++20 range
- {
- auto info = compileFile(argv[i]);
- allCommand += info.filestr + tostr(info.arguments);
- std::cout << "Executing:\t" << allCommand << endl;
- //system(allCommand); // TODO don't system random shit from users...
- }
- }
- CompileState compileFile(std::string fileName)
- {
- ifstream file{fileName};
- CompileState state;
- for (std::string c; getline(file, c); ) compileCommand(c, state);
- state.filestr = tostr(state.files);
- if(state.version) state.filestr += " -std=" + state.version.str;
- if(state.output) state.arguments.push_back("-o " + state.output);
- return state;
- }
- void compileCommand(const string& command, CompileState& state)
- {
- if(command[0] == '-') state.section = Section::none;
- if (command == "-FILES" || command == "-F") state.section = Section::files;
- else if (command == "-WARNINGS" || command == "-W") state.section = Section::warnings;
- else if (command == "-DEFAULT_WARNINGS") state.arguments.append("-Wall -Wextra -Wpedantic");
- else if (startWith(command, "-VERSION=") || startWith(command,"-V=")
- {
- auto sep = command.find('=');
- auto vers = command.substr(sep+1);
- try {
- int ver = stoi(vers);
- if(state.version) { std::log << "Multiple VERSIONs set, overwriting "
- << state.version << " with " << vers << "\n"; }
- state.version = {ver, vers};
- } catch(...) {
- std::log << "Invalid version provided '" << vers << "'\n";
- }
- }
- else if (startWith(command, "-OUTPUT=") || startWith(command, "-O="))
- {
- sub = command.substr(command.find("=")+1);
- if(!state.output.empty()) std::log << "Multiple output commands! Overwriting '"
- << state.output << "' with '" << sub << "'\n";
- state.output = sub;
- }
- else if (state.section != Section::none)
- {
- switch(state.section)
- {
- case Section::files:
- files.push_back(command);
- break;
- case Section::warnings:
- state.arguments.push_back("-W" + command);
- break;
- case default:
- std::log << "Unknown command with no state opened: '" << command << "'\n";
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement