#include "shell.h" #include "parser.h" #include "commands.h" #include "errors.h" #include #include #include //--- // e //--- struct _e_args { std::string space_name; std::vector values; }; static _e_args parse_e(Session &session, Parser &parser) { _e_args args {}; parser.option("vspace", [&args](std::string const &value) { args.space_name = value; }); parser.accept_options(); VirtualSpace *space = session.current_space; if(!args.space_name.empty()) { space = session.get_space(args.space_name); 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); } } while(!parser.at_end()) args.values.push_back(parser.expr(space)); parser.end(); return args; } void _e(Session &, std::string, std::vector const &values) { for(long value: values) { long print_val = labs(value); /* Hexa format */ int length = (print_val <= (1ll << 32) ? 8 : 16) + 2 + (value < 0); std::string format = fmt::format("{{:#0{}x}}", length); fmt::print(format, value); if(print_val <= 100 || print_val % 100 <= 1 || print_val % 100 >= 99) fmt::print(" = {}", print_val); fmt::print("\n"); } } static ShellCommand _e_cmd( "e", [](Session &s, Parser &p) { auto const &args = parse_e(s, p); _e(s, args.space_name, args.values); }, [](Session &s, Parser &p) { parse_e(s, p); }, "Evaluate expression", R"( e [vspace=] [...] Evaluates the specified expressions. The expressions may include syscall references (%0ab), named symbols (TRA), the current cursor ($), and arithmetic expressions. The parser doesn't accept arithmetic expressions directly on the command-line; they must be placed within parentheses. The resulting values undergo a simple analysis which recovers symbol names and syscall addresses within the named virtual space, or using the current virtual space if not provided. e TRA ($+2) Evaluate the address of the TRA register, and the address of the next instruction. )");