shell: refactor main loop
This commit is contained in:
parent
356d09e52d
commit
12d41ac823
|
@ -151,7 +151,7 @@ char *autocomplete(char const *text, int state)
|
|||
// Shell routine
|
||||
//---
|
||||
|
||||
static std::string read_interactive(Session &s, bool &leave)
|
||||
static bool read_interactive(Session &s, std::string &cmdline)
|
||||
{
|
||||
std::string prompt = "no_vspace> ";
|
||||
if(s.current_space) {
|
||||
|
@ -185,16 +185,14 @@ static std::string read_interactive(Session &s, bool &leave)
|
|||
|
||||
/* Get a command to execute */
|
||||
char *cmd_ptr = readline(prompt.c_str());
|
||||
if(!cmd_ptr) {
|
||||
leave = true;
|
||||
return "";
|
||||
}
|
||||
if(!cmd_ptr)
|
||||
return true;
|
||||
|
||||
std::string cmd = cmd_ptr;
|
||||
cmdline = std::string(cmd_ptr);
|
||||
if(strlen(cmd_ptr) > 0)
|
||||
add_history(cmd_ptr);
|
||||
free(cmd_ptr);
|
||||
return cmd;
|
||||
return false;
|
||||
}
|
||||
|
||||
char const *help_message =
|
||||
|
@ -340,6 +338,19 @@ static void load_initial_project(
|
|||
FxOS_log(ERR, "'%s' is not a regular file or folder", input.c_str());
|
||||
}
|
||||
|
||||
static void global_help(void)
|
||||
{
|
||||
for(auto const &it: commands) {
|
||||
fmt::print(" {:5s} {}\n", it.first, it.second->short_description);
|
||||
}
|
||||
}
|
||||
|
||||
static void command_help(std::string const &cmd)
|
||||
{
|
||||
fmt::print("{}: {}\n\n{}\n", cmd, commands[cmd]->short_description,
|
||||
commands[cmd]->long_description);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
/* Parse command-line options first */
|
||||
|
@ -419,32 +430,28 @@ int main(int argc, char **argv)
|
|||
_dot(s, fxosrc_files, true);
|
||||
}
|
||||
|
||||
/* Stores whether we have already idled once, handling extra rom
|
||||
and execute options */
|
||||
/* Whether we have reached an idle state after parsing fxosrc files */
|
||||
bool has_idled = false;
|
||||
/* Command line input by user */
|
||||
std::string cmdline;
|
||||
|
||||
/* Shell main loop */
|
||||
while(true) {
|
||||
/* Get a command if there isn't a file being executed */
|
||||
/* Handle initial fxosrc files and the CLI --execute option */
|
||||
if(lex_idle()) {
|
||||
/* If we need to execute a command */
|
||||
if(!opts.execute_arg.empty()) {
|
||||
if(opts.execute_arg != "") {
|
||||
if(has_idled)
|
||||
exit(0);
|
||||
else
|
||||
lex_repl(opts.execute_arg);
|
||||
}
|
||||
else {
|
||||
while(sigsetjmp(sigint_buf, 1) != 0) {}
|
||||
|
||||
bool leave = false;
|
||||
std::string cmdline = read_interactive(s, leave);
|
||||
if(leave && s.confirmProjectUnload())
|
||||
break;
|
||||
lex_repl(cmdline);
|
||||
}
|
||||
|
||||
/* We have already handled FILE and --execute, don't do it again */
|
||||
has_idled = true;
|
||||
}
|
||||
/* Or read from the command line */
|
||||
if(lex_idle()) {
|
||||
while(sigsetjmp(sigint_buf, 1) != 0) {}
|
||||
if(read_interactive(s, cmdline) && s.confirmProjectUnload())
|
||||
break;
|
||||
lex_repl(cmdline);
|
||||
has_idled = true;
|
||||
}
|
||||
|
||||
|
@ -459,10 +466,7 @@ int main(int argc, char **argv)
|
|||
if(parser.lookahead().type == T::END)
|
||||
continue;
|
||||
if(parser.lookahead().type == '?') {
|
||||
for(auto const &it: commands) {
|
||||
fmt::print(
|
||||
" {:5s} {}\n", it.first, it.second->short_description);
|
||||
}
|
||||
global_help();
|
||||
continue;
|
||||
}
|
||||
std::string cmd = parser.symbol("command");
|
||||
|
@ -470,17 +474,13 @@ int main(int argc, char **argv)
|
|||
if(cmd == "q" && parser.lookahead().type != '?'
|
||||
&& s.confirmProjectUnload())
|
||||
break;
|
||||
if(cmd == "p") {
|
||||
if(cmd == "_p") {
|
||||
parser.dump_command();
|
||||
}
|
||||
else if(commands.count(cmd)) {
|
||||
if(parser.lookahead().type == '?') {
|
||||
fmt::print("{}: {}\n\n{}\n", cmd,
|
||||
commands[cmd]->short_description,
|
||||
commands[cmd]->long_description);
|
||||
continue;
|
||||
}
|
||||
if(commands[cmd]->function)
|
||||
if(parser.lookahead().type == '?')
|
||||
command_help(cmd);
|
||||
else if(commands[cmd]->function)
|
||||
commands[cmd]->function(s, parser);
|
||||
}
|
||||
else {
|
||||
|
@ -492,15 +492,7 @@ int main(int argc, char **argv)
|
|||
}
|
||||
|
||||
/* Exhaust command input (if not all used by the command) */
|
||||
while(true) {
|
||||
try {
|
||||
parser.exhaust_until_separator();
|
||||
break;
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
FxOS_log(ERR, "%s", e.what());
|
||||
}
|
||||
}
|
||||
parser.exhaust_until_separator();
|
||||
}
|
||||
|
||||
/* Save command history */
|
||||
|
|
|
@ -135,6 +135,9 @@ void Parser::exhaust_until_separator()
|
|||
}
|
||||
catch(SyntaxError const &e) {
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
FxOS_log(ERR, "%s", e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue