shell: fix syntax error + autocompletion exception

Somehow there were two types of syntax errors, and the autocompletion
code was not catching the correct one.
This commit is contained in:
Lephenixnoir 2023-08-23 15:39:23 +02:00
parent 0373ae50fe
commit 61c3714404
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
5 changed files with 21 additions and 19 deletions

View File

@ -443,7 +443,8 @@ marked as part of functions, data, interrupt handlers, etc.
)");
static ShellCommand _if_cmd(
"if", [](Session &s, Parser &p) {
"if",
[](Session &s, Parser &p) {
auto args = parse_if(s, p);
_if(s, args);
},

View File

@ -94,7 +94,7 @@ static bool lex_pop()
}
/* Error messages and exceptions */
static void err(char const *format, ...)
void lex_err(char const *format, ...)
{
static char buf[1024];
@ -103,8 +103,13 @@ static void err(char const *format, ...)
vsnprintf(buf, 1024, format, args);
va_end(args);
Input const &in = lex_current_input();
throw SyntaxError(in.filename.c_str(), in.line, buf);
if(lex_idle()) {
throw SyntaxError("(idle)", 0, buf);
}
else {
Input const &in = lex_current_input();
throw SyntaxError(in.filename.c_str(), in.line, buf);
}
}
/* Parse numerical values */
@ -194,9 +199,9 @@ space [ \t]+
<*>"?" { return '?'; }
/* Generic error and word boundaries violations */
<*>{syscall}{letter} { err("invalid syscall number '%s'", yytext); }
<*>{num}{letter} { err("invalid numerical value '%s'", yytext); }
<*>. { err("invalid token near '%s'", yytext); }
<*>{syscall}{letter} { lex_err("invalid syscall number '%s'", yytext); }
<*>{num}{letter} { lex_err("invalid numerical value '%s'", yytext); }
<*>. { lex_err("invalid token near '%s'", yytext); }
<<EOF>> { if(lex_pop()) return T::END; }
%%

View File

@ -15,6 +15,7 @@
#include "shell.h"
#include "theme.h"
#include "parser.h"
#include "errors.h"
#include "commands.h"
#include <fxos/util/log.h>
#include <fxos/semantics.h>
@ -106,7 +107,7 @@ Parser::CompletionRequest parse_until_autocomplete(
catch(Parser::CompletionRequest r) {
return r;
}
catch(Parser::SyntaxError &e) {
catch(SyntaxError &e) {
/* Ignore syntax errors, just don't autocomplete */
}

View File

@ -107,7 +107,7 @@ void Parser::end()
{
m_options.clear();
if(!at_end())
throw SyntaxError("expected end of command");
lex_err("expected end of command");
}
void Parser::exhaust()
@ -166,16 +166,15 @@ Token Parser::expect(std::initializer_list<T> types, bool ignore_spaces)
if(!correct_type) {
static char err[128];
int offset = sprintf(err, "expected ");
int offset = 0;
for(auto it = types.begin(); it != types.end(); it++) {
offset += sprintf(err + offset, "%s%s%s",
(it != types.begin() && it + 1 == types.end() ? "or " : ""),
(*it).str().c_str(), (it + 1 == types.end() ? "; " : ", "));
(*it).str().c_str(), (it + 1 == types.end() ? "" : ", "));
}
sprintf(err + offset, "instead found %s", m_la.str().c_str());
throw SyntaxError(err);
lex_err("expected %s; instead found %s", err, m_la.str().c_str());
}
Token t = feed(ignore_spaces);

View File

@ -95,6 +95,8 @@ void lex_repl(std::string input);
/* Lex the input coming from these files, sequentially */
void lex_include(std::vector<std::string> files);
/* For the parser: format and throw a syntax error at current location */
void lex_err(char const *format, ...);
/* For the parser: get one token from the current source */
Token lex_read();
@ -166,12 +168,6 @@ public:
// Completion system
//---
class SyntaxError: public std::invalid_argument
{
public:
SyntaxError(char const *what): std::invalid_argument(what) {}
};
/* A completion request is thrown by the parser when in completion mode to
signal the expected next element */
struct CompletionRequest