diff --git a/shell/e.cpp b/shell/e.cpp index 337d870..ce4e31c 100644 --- a/shell/e.cpp +++ b/shell/e.cpp @@ -26,21 +26,21 @@ static _e_args parse_e(Session &session, Parser &parser) parser.accept_options(); - VirtualSpace *space; - if(!args.space_name.empty()) + VirtualSpace *space = session.current_space; + if(!args.space_name.empty()) { space = session.get_space(args.space_name); - else - space = session.current_space; - - if(space) - while(!parser.at_end()) - args.values.push_back(parser.expr(space)); - else { - FxOS_log(ERR, "virtual space '%s' does not exist", args.space_name); - parser.exhaust(); + if(!space) { + std::string msg = + format("virtual space '%s' does not exist", args.space_name); + if(parser.completing()) + throw Parser::CompletionRequest("_error", msg); + else + FxOS_log(ERR, "%s", msg); + } } - // TODO: Error message when session specified in _e does not exist + while(!parser.at_end()) + args.values.push_back(parser.expr(space)); parser.end(); return args; diff --git a/shell/lexer.l b/shell/lexer.l index 13cd7f0..1def144 100644 --- a/shell/lexer.l +++ b/shell/lexer.l @@ -143,7 +143,7 @@ num_suffix [kMG] num ({num_hex}|{num_dec}|{num_bin}){num_suffix}? syscall [%][a-fA-F0-9]+ -option [a-zA-Z]+=[^ ]+ +option [a-zA-Z]+=[^ ]* symbol [a-zA-Z_.][a-zA-Z0-9_.]* space [ \t]+ diff --git a/shell/main.cpp b/shell/main.cpp index 294c129..249f1b6 100644 --- a/shell/main.cpp +++ b/shell/main.cpp @@ -129,6 +129,11 @@ char *autocomplete(char const *text, int state) options = complete_region(text); else if(r.category == "symbol" && r.space != nullptr) options = complete_symbol(text, r.space); + else if(r.category == "_error") { + options.clear(); + options.push_back("(ERROR) " + r.value); + options.push_back("."); + } else options.clear(); i = 0; diff --git a/shell/parser.cpp b/shell/parser.cpp index c5f7319..cd3b264 100644 --- a/shell/parser.cpp +++ b/shell/parser.cpp @@ -116,6 +116,11 @@ void Parser::exhaust() feed(); } +bool Parser::completing() const +{ + return m_complete; +} + void Parser::skip_separators() { while(m_la.type == T::SEPARATOR) @@ -319,13 +324,12 @@ long Parser::atom() if(os && (int)opt->value < os->syscall_count()) val = os->syscall(opt->value); } - else { - throw CommandError("symbol '{}' is undefined", t.value.STRING); - } + else if(!m_complete) + FxOS_log(ERR, "symbol '%s' is undefined", t.value.STRING); } - else - throw CommandError( - "cannot query symbol '{}', no virtual space", t.value.STRING); + else if(!m_complete) + FxOS_log(ERR, "cannot query symbol '%s' (no virtual space)", + t.value.STRING); return val; } else if(t.type == T::SYSCALL) { diff --git a/shell/parser.h b/shell/parser.h index b77c0ba..9de9771 100644 --- a/shell/parser.h +++ b/shell/parser.h @@ -117,6 +117,10 @@ public: void end(); /* Exhaust all input (usually after encountering an error) */ void exhaust(); + /* Whether we are parsing for autocompletion. This is only available to + allow appropriate decisions about printing vs. ignoring error messages. + Do not change parsing rules based on this information! */ + bool completing() const; /* Expect a token of this type, or of any of the listed types */ Token expect(T type, bool ignore_spaces=true);