From c58cd882994d2ad474029a88e36973767847f50d Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 5 Feb 2009 02:43:58 -0400 Subject: Reworked how the REPL is handled. --- src/main.cc | 321 ++++++++++++++++++++++++++++++++-------------------------- src/report.cc | 13 +-- src/report.h | 63 +++++++++++- src/work.cc | 11 +- src/work.h | 2 +- 5 files changed, 244 insertions(+), 166 deletions(-) (limited to 'src') diff --git a/src/main.cc b/src/main.cc index 06ce8563..3e9dbb9c 100644 --- a/src/main.cc +++ b/src/main.cc @@ -36,27 +36,6 @@ using namespace ledger; namespace { - char * stripwhite (char * string) - { - if (! string) - return NULL; - - register char *s, *t; - - for (s = string; isspace (*s); s++) - ; - - if (*s == 0) - return (s); - - t = s + strlen (s) - 1; - while (t > s && isspace (*t)) - t--; - *++t = '\0'; - - return s; - } - strings_list split_arguments(char * line) { strings_list args; @@ -70,40 +49,53 @@ namespace { return args; } + char * prompt_string(const ptr_list& report_stack) + { + static char prompt[32]; + std::size_t i; + for (i = 0; i < report_stack.size(); i++) + prompt[i] = ']'; + prompt[i++] = ' '; + prompt[i] = '\0'; + return prompt; + } + + void report_error(const std::exception& err) + { + std::cout.flush(); // first display anything that was pending + + if (caught_signal == NONE_CAUGHT) { + // Display any pending error context information + string context = error_context(); + if (! context.empty()) + std::cerr << context << std::endl; + + std::cerr << "Error: " << err.what() << std::endl; + } else { + caught_signal = NONE_CAUGHT; + } + } + /** * @return \c true if a command was actually executed; otherwise, it probably * just resulted in setting some options. */ - bool execute_command(session_t& session, - ledger::strings_list args, - char ** envp = NULL) + void execute_command(session_t& session, + report_t& report, + strings_list args, + bool at_repl) { - // Create the report object, which maintains state relating to each - // command invocation. Because we're running from main(), the distinction - // between session and report doesn't really matter, but if a GUI were - // calling into Ledger it would have one session object per open document, - // with a separate report_t object for each report it generated. - std::auto_ptr manager(new report_t(session)); - report_t& report(*manager.get()); + // Create a new report command object based on the current one, so that + // the next command's option don't corrupt state. + std::auto_ptr manager(new report_t(report)); - session.global_scope = &report; + // Process the command verb, arguments and options + args = read_command_arguments(*manager.get(), args); + if (args.empty()) + return; - // Read the user's options, in the following order: - // - // 1. environment variables (LEDGER_