X-Git-Url: https://git.armaanb.net/?a=blobdiff_plain;f=src%2Fmain.cpp;h=ae69ebb6f09f1e6ea52e4d6a5a6a9eb1ff542b97;hb=HEAD;hp=269d7394fe5868a86770ae7c9b7a53ac9b8c43f9;hpb=eb1e18ee5dc8235e48dd5184f60c13c33cad6add;p=gen-shell.git diff --git a/src/main.cpp b/src/main.cpp index 269d739..ae69ebb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,188 +1,92 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// Copyright 2006 - 2017, Paul Beckingham, Federico Hernandez, 2020 Armaan Bhojwani -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// http://www.opensource.org/licenses/mit-license.php -// -//////////////////////////////////////////////////////////////////////////////// +// gen-shell - the generic REPL +// Copyright (c) 2021, Armaan Bhojwani -#include #include +#include "sarge.h" + #include #include -#include -#include -#include -#include -#include -#ifdef HAVE_READLINE #include #include -#endif - -// tasksh commands. -int cmdHelp (); -int cmdDiagnostics (); -int cmdReview (const std::vector &, bool); -int cmdShell (const std::vector &); -std::string promptCompose (); -std::string findTaskwarrior (); //////////////////////////////////////////////////////////////////////////////// -static void welcome () -{ - std::cout << PACKAGE_STRING << "\n"; - cmdHelp (); -} -//////////////////////////////////////////////////////////////////////////////// -const std::string getResponse (const std::string& prompt) -{ - std::string response {""}; +using namespace std; - // Display prompt, get input. -#ifdef HAVE_READLINE - char *line_read = readline (prompt.c_str ()); - if (! line_read) - { - std::cout << "\n"; - response = ""; - } - else - { - // Save history. - if (*line_read) - add_history (line_read); - - response = std::string (line_read); - free (line_read); - } -#else - std::cout << prompt; - std::getline (std::cin, response); - if (std::cin.eof () == 1) - { +const std::string +getResponse(const std::string & prompt) { + std::string response { + "" + }; + + // Display prompt, get input + char * line_read = readline(prompt.c_str()); + if (!line_read) { std::cout << "\n"; response = ""; + } else { + if (*line_read) { + add_history(line_read); + } + + response = std::string(line_read); + free(line_read); } -#endif return response; } //////////////////////////////////////////////////////////////////////////////// -static int commandLoop (bool autoClear) -{ - // Compose the prompt. - auto prompt = promptCompose (); - - // Display prompt, get input. - auto command = getResponse (prompt); - // Obey Taskwarrior's rc.tasksh.autoclear. - if (autoClear) - std::cout << "\033[2J\033[0;0H"; - - int status = 0; - if (! isatty (fileno (stdin)) && command == "") - { - status = -1; - } - else if (command != "") - { - auto args = split (command, ' '); - - // Dispatch command. - if (args[0] == "") status = -1; - else if (closeEnough ("exit", args[0], 3)) status = -1; - else if (closeEnough ("quit", args[0], 3)) status = -1; - else if (closeEnough ("help", args[0], 3)) status = cmdHelp (); - else if (closeEnough ("diagnostics", args[0], 3)) status = cmdDiagnostics (); - else if (closeEnough ("review", args[0], 3)) status = cmdReview (args, autoClear); - else if (closeEnough ("exec", args[0], 3) || - args[0][0] == '!') status = cmdShell (args); - else if (command != "") - { - command = "task " + command; - std::cout << "[" << command << "]\n"; - system (command.c_str ()); - - // Deliberately ignoreѕ taskwarrior exit status, otherwise empty filters - // cause the shell to terminate. - } +int +main(int argc, char** argv) +{ + // Command line arguments + Sarge sarge; + + sarge.setArgument("c", "command", "Command to convert to REPL", true); + sarge.setArgument("h", "help", "Show this message.", false); + sarge.setArgument("p", "prompt", "Define a custom prompt", true); + sarge.setArgument("q", "quotes", "Treat whole input as argv[1]", false); + sarge.setDescription("Make a REPL from any executable"); + sarge.setUsage("gen-shell "); + + if (!sarge.parseArguments(argc, argv)) { + std::cerr << "Could not parse command line arguments" << std::endl; + return 1; } - return status; -} + if (sarge.exists("help")) { + sarge.printHelp(); + return 0; + } -//////////////////////////////////////////////////////////////////////////////// -int main (int argc, const char** argv) -{ - int status = 0; + string arg_cmd; + sarge.getFlag("command", arg_cmd); - // Lightweight version checking that doesn't require initialization or any I/O. - if (argc == 2 && !strcmp (argv[1], "--version")) - { - std::cout << VERSION << "\n"; + string prompt = ""; + sarge.getFlag("prompt", prompt); + if (prompt == "") { + prompt = "% "; } - else - { - try - { - // Get the Taskwarrior rc.tasksh.autoclear Boolean setting. - bool autoClear = false; - std::string input; - std::string output; - execute ("task", {"_get", "rc.tasksh.autoclear"}, input, output); - output = lowerCase (output); - autoClear = (output == "true\n" || - output == "1\n" || - output == "y\n" || - output == "yes\n" || - output == "on\n"); - - if (isatty (fileno (stdin))) - welcome (); - - while ((status = commandLoop (autoClear)) == 0) - ; - } - catch (const std::string& error) - { - std::cerr << error << "\n"; - status = -1; - } - - catch (...) - { - std::cerr << "Unknown error." << "\n"; - status = -2; + // Do the stuffs! + while (true) { + auto command = getResponse(prompt); + + if (command == "" || command == "exit" || command == "quit" ) { + return 0; + } else { + string whole_command = arg_cmd + " "; + if (sarge.exists("quotes")) { + whole_command = whole_command + "\"" + command + "\""; + } else { + whole_command += command; + } + system(whole_command.c_str()); } } - - // Returning -1 drops out of the command loop, but gets translated to 0 here, - // so that there is a clean way to exit. - return status == -1 ? 0 : status; } ////////////////////////////////////////////////////////////////////////////////