// vim: filetype=cpp #include #include #include #include #include #include "config.h" #include "tclap/CmdLine.h" #include "json.hpp" #include "bottles.hpp" #include "cellar.hpp" #include "commands.hpp" #include "output.hpp" #include "version.hpp" /*[[[cog import cog with open("src/modules.txt") as modules: for module in modules: cog.outl("#include \"internal/{0}.hpp\"".format(module.strip())) ]]]*/ //[[[end]]] using namespace std; using namespace cellar; using json = nlohmann::json; bool cellar::verbose; void cellar::print_header() { output::statement("cellar - bottle management tool for WINE connoisseurs"); output::statement(version::short_version()); } int main(int argc, char* argv[]) { output::detect_colors(); if (argc == 1) { print_header(); cout << "\n(try \"cellar help\" if you're confused)" << endl; return 0; } try { const string desc = "bottle management tool for WINE connoisseurs"; const string versionstr = version::short_version(); TCLAP::CmdLine cmdparse(desc, ' ', versionstr, false); TCLAP::SwitchArg verbosearg("v", "verbose", "Enables extra output"); cmdparse.add(verbosearg); TCLAP::UnlabeledValueArg command("command", "Specific command to run.", true, "help", "command"); cmdparse.add(command); TCLAP::UnlabeledMultiArg subargs("subargs", "Sub-arguments", false, "", "subarg"); cmdparse.add(subargs); cmdparse.parse(argc, argv); verbose = verbosearg.getValue(); // hardcoded because it's special vector core_cmdnames; // mostly for verbose output for (auto item : commands::core_commands()) { commands::command_map[item.first] = item.second; core_cmdnames.push_back(item.first); } if (verbose) { // handling it here for efficiency stringstream commandstring; commandstring << "loading from core: "; for (string item : core_cmdnames) { commandstring << item << " "; } output::statement(commandstring.str(), true); } // as above, but cogged from src/modules.txt // BULLSHIT: trying to use str.format on this string causes bizarre compiler errors /*[[[cog import cog with open("src/modules.txt") as modules: for module in modules: cog.out(""" vector """ + module.strip() + """_cmdnames; for (auto item : commands::""" + module.strip() + """_commands()) { commands::command_map[item.first] = item.second; """ + module.strip() + """_cmdnames.push_back(item.first); } if (verbose) { stringstream commandstring; commandstring << "loading from """ + module.strip() + """: "; for (string item : """ + module.strip() + """_cmdnames) { commandstring << item << " "; } output::statement(commandstring.str(), true); } """, dedent=True, trimblanklines=True) ]]]*/ //[[[end]]] string usercmd = command.getValue(); if (commands::command_map.count(usercmd) > 0) { vector subargv; stringstream sstr; sstr << "cellar "; sstr << usercmd; subargv.push_back(sstr.str()); for (auto item : subargs.getValue()) { subargv.push_back(item); } commands::command_map[usercmd](subargv.size(), subargv); } else { stringstream errstr; errstr << "invalid command: " << usercmd; output::error(errstr.str()); return 1; } return 0; } catch (TCLAP::ArgException &exc) { cerr << "Invalid argument. (" << exc.argId() << ": " << exc.error() << ")" << endl; return 1; } }