shell: refactor main loop

This commit is contained in:
Lephenixnoir 2023-09-23 21:36:14 +02:00
parent 356d09e52d
commit 12d41ac823
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
2 changed files with 40 additions and 45 deletions

View File

@ -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 */

View File

@ -135,6 +135,9 @@ void Parser::exhaust_until_separator()
}
catch(SyntaxError const &e) {
}
catch(std::exception &e) {
FxOS_log(ERR, "%s", e.what());
}
}
}