# # # patch "commands.cc" # from [bcb6398ecd2a30e771549f532493728dfbb84c43] # to [dd318c5ee0564c0745c5c6dec455be4c573e54ba] # # patch "commands.hh" # from [23cd185ee52305c33ef1dc78e617bd8af51fae35] # to [d2d27b5304bb815af7dacb768fdb548f66016a48] # # patch "monotone.cc" # from [6833dc2929eb38b5b4ef465e0d45692503be1f08] # to [d9da9bb00dbed1bba52892eac09aa974e8b2c2b0] # ============================================================ --- commands.cc bcb6398ecd2a30e771549f532493728dfbb84c43 +++ commands.cc dd318c5ee0564c0745c5c6dec455be4c573e54ba @@ -642,41 +642,29 @@ namespace commands explain_cmd_usage(ident, out); } - int process(app_state & app, command_id const & ident, - args_vector const & args) + void process(app_state & app, command_id const & ident, + args_vector const & args) { command * cmd = CMD_REF(__root__)->find_command(ident); - if (cmd->is_leaf()) - { - L(FL("executing command '%s'") % join_words(ident)); + N(!(!cmd->is_leaf() && cmd->parent() == CMD_REF(__root__)), + F("command '%s' is invalid; it is a group") % join_words(ident)); - // at this point we process the data from _MTN/options if - // the command needs it. - if (cmd->use_workspace_options()) - app.process_options(); + N(!(!cmd->is_leaf() && args.empty()), + F("no subcommand specified for '%s'") % join_words(ident)); - cmd->exec(app, ident, args); - return 0; - } - else if (cmd->parent() == CMD_REF(__root__)) - { - N(false, - F("command '%s' is invalid; it is a group") % join_words(ident)); - } - else - { - if (args.empty()) - W(F("no subcommand specified for '%s'") % join_words(ident)); - else - W(F("could not match '%s' to a subcommand of '%s'") % - join_words(args) % join_words(ident)); - // XXX Oh, oh, what to do. This is a syntax error, so an usage is - // probably worth it... but then, the return value of this function - // becomes useless... - throw usage(ident); - return 1; - } + N(!(!cmd->is_leaf() && !args.empty()), + F("could not match '%s' to a subcommand of '%s'") % + join_words(args) % join_words(ident)); + + L(FL("executing command '%s'") % join_words(ident)); + + // at this point we process the data from _MTN/options if + // the command needs it. + if (cmd->use_workspace_options()) + app.process_options(); + + cmd->exec(app, ident, args); } options::options_type command_options(command_id const & ident) ============================================================ --- commands.hh 23cd185ee52305c33ef1dc78e617bd8af51fae35 +++ commands.hh d2d27b5304bb815af7dacb768fdb548f66016a48 @@ -26,8 +26,8 @@ namespace commands { command_id make_command_id(std::string const & path); void explain_usage(command_id const & cmd, std::ostream & out); command_id complete_command(args_vector const & args); - int process(app_state & app, command_id const & ident, - args_vector const & args); + void process(app_state & app, command_id const & ident, + args_vector const & args); options::options_type command_options(command_id const & ident); }; ============================================================ --- monotone.cc 6833dc2929eb38b5b4ef465e0d45692503be1f08 +++ monotone.cc d9da9bb00dbed1bba52892eac09aa974e8b2c2b0 @@ -266,7 +266,11 @@ cpp_main(int argc, char ** argv) } else { - return commands::process(app, cmd, app.opts.args); + commands::process(app, cmd, app.opts.args); + // The command will raise any problems itself through + // exceptions. If we reach this point, it is because it + // worked correctly. + return 0; } } catch (option::option_error const & e)