-////////////////////////////////////////////////////////////////////////////////
-//
-// 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 <me@armaanb.net>
-#include <cmake.h>
#include <iostream>
+#include "sarge.h"
+
#include <vector>
#include <string>
-#include <cstring>
-#include <cstdio>
-#include <stdlib.h>
-#include <unistd.h>
-#include <shared.h>
-#ifdef HAVE_READLINE
#include <readline/readline.h>
#include <readline/history.h>
-#endif
-std::string promptCompose ();
+////////////////////////////////////////////////////////////////////////////////
-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 = "<EOF>";
- }
- 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 = "<EOF>";
+ } 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;
+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 <options>");
+
+ if (!sarge.parseArguments(argc, argv)) {
+ std::cerr << "Could not parse command line arguments" << std::endl;
+ return 1;
}
- else if (command != "")
- {
- auto args = split (command, ' ');
-
- // Dispatch command.
- if (args[0] == "<EOF>") status = -1;
- else if (closeEnough ("exit", args[0], 3)) status = -1;
- else if (closeEnough ("quit", args[0], 3)) status = -1;
- else if (command != "")
- {
- command = "echo " + command + " | lolcat ";
- std::cout << "[" << command << "]\n";
- system (command.c_str ());
-
- // Deliberately ignoreѕ taskwarrior exit status, otherwise empty filters
- // cause the shell to terminate.
- }
+
+ if (sarge.exists("help")) {
+ sarge.printHelp();
+ return 0;
}
- return status;
-}
+ string arg_cmd;
+ sarge.getFlag("command", arg_cmd);
-////////////////////////////////////////////////////////////////////////////////
-int main (int argc, const char** argv)
-{
- int status = 0;
-
- // 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");
-
- 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 == "<EOF>" || 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;
}
////////////////////////////////////////////////////////////////////////////////