# # # patch "cmd.hh" # from [d523c2725e70ad02fae167b85a7f964c44a03ff8] # to [035c6902d1e393f75cd1038c48a19f2305640014] # # patch "cmd_list.cc" # from [93eee2d3af29db17a6b63805b00c35b34a508306] # to [1524a512fa17638d091937605591bc9d74c56c64] # # patch "commands.cc" # from [d2caef21d0c131f5669e29d1228befd0469549ab] # to [38463c25992cc776d9150992e6d31c27509c612b] # ============================================================ --- cmd.hh d523c2725e70ad02fae167b85a7f964c44a03ff8 +++ cmd.hh 035c6902d1e393f75cd1038c48a19f2305640014 @@ -55,6 +55,8 @@ namespace commands std::string const & name, std::vector const & args) = 0; }; + + command * find_command(command const * startcmd, std::string const & name); }; inline std::vector @@ -161,7 +163,18 @@ void commands::cmd_ ## C::exec(app_state std::string const & name, \ std::vector const & args) \ { \ - I(false); \ + if (args.size() == 0) \ + throw usage(name); \ + \ + vector< utf8 >::const_iterator i = args.begin(); \ + ++i; \ + vector< utf8 > removed (i, args.end()); \ + /* XXX Command completion... */ \ + command * child = find_command(this, idx(args, 0)()); \ + if (child == NULL) \ + throw usage(name); \ + else \ + child->exec(app, idx(args, 0)(), removed); \ } // Use this for commands that should specifically _not_ look for an ============================================================ --- cmd_list.cc 93eee2d3af29db17a6b63805b00c35b34a508306 +++ cmd_list.cc 1524a512fa17638d091937605591bc9d74c56c64 @@ -39,8 +39,10 @@ using std::vector; using std::string; using std::vector; -static void -ls_certs(string const & name, app_state & app, vector const & args) +CMD(certs, "", "list", "ID", + N_("Lists certificates attached to an identifier"), + N_(""), + options::opts::depth | options::opts::exclude) { if (args.size() != 1) throw usage(name); @@ -140,9 +142,10 @@ ls_certs(string const & name, app_state guard.commit(); } -static void -ls_keys(string const & name, app_state & app, - vector const & args) +CMD(keys, "", "list", "[PATTERN]", + N_("Lists keys that match a pattern"), + N_(""), + options::opts::depth | options::opts::exclude) { vector pubs; vector privkeys; @@ -233,8 +236,10 @@ ls_keys(string const & name, app_state & } } -static void -ls_branches(string name, app_state & app, vector const & args) +CMD(branches, "", "list", "[PATTERN]", + N_("Lists branches in the database that match a pattern"), + N_(""), + options::opts::depth | options::opts::exclude) { globish inc("*"); globish exc; @@ -259,8 +264,10 @@ ls_branches(string name, app_state & app } } -static void -ls_epochs(string name, app_state & app, vector const & args) +CMD(epochs, "", "list", "[BRANCH [...]]", + N_("Lists the current epoch of branches that match a pattern"), + N_(""), + options::opts::depth | options::opts::exclude) { map epochs; app.db.get_epochs(epochs); @@ -287,8 +294,10 @@ ls_epochs(string name, app_state & app, } } -static void -ls_tags(string name, app_state & app, vector const & args) +CMD(tags, "", "list", "", + N_("Lists all tags in the database"), + N_(""), + options::opts::depth | options::opts::exclude) { set tags; app.get_project().get_tags(tags); @@ -301,8 +310,10 @@ ls_tags(string name, app_state & app, ve } } -static void -ls_vars(string name, app_state & app, vector const & args) +CMD(vars, "", "list", "[DOMAIN]", + N_("Lists variables in the whole database or a domain"), + N_(""), + options::opts::depth | options::opts::exclude) { bool filterp; var_domain filter; @@ -333,8 +344,10 @@ ls_vars(string name, app_state & app, ve } } -static void -ls_known(app_state & app, vector const & args) +CMD(known, "", "list", "", + N_("Lists workspace files that belong to the current branch"), + N_(""), + options::opts::depth | options::opts::exclude) { roster_t new_roster; temp_node_id_source nis; @@ -373,9 +386,10 @@ ls_known(app_state & app, vector c } } -static void -ls_unknown_or_ignored(app_state & app, bool want_ignored, - vector const & args) +CMD(unknown, "ignored", "list", "", + N_("Lists workspace files that do not belong to the current branch"), + N_(""), + options::opts::depth | options::opts::exclude) { app.require_workspace(); @@ -390,18 +404,23 @@ ls_unknown_or_ignored(app_state & app, b app.work.find_unknown_and_ignored(mask, roots, unknown, ignored); - if (want_ignored) + if (name == "ignored") for (path_set::const_iterator i = ignored.begin(); i != ignored.end(); ++i) cout << file_path(*i) << '\n'; else - for (path_set::const_iterator i = unknown.begin(); - i != unknown.end(); ++i) - cout << file_path(*i) << '\n'; + { + I(name == "unknown"); + for (path_set::const_iterator i = unknown.begin(); + i != unknown.end(); ++i) + cout << file_path(*i) << '\n'; + } } -static void -ls_missing(app_state & app, vector const & args) +CMD(missing, "", "list", "", + N_("Lists files that belong to the branch but are not in the workspace"), + N_(""), + options::opts::depth | options::opts::exclude) { temp_node_id_source nis; roster_t current_roster_shape; @@ -422,8 +441,10 @@ ls_missing(app_state & app, vector } -static void -ls_changed(app_state & app, vector const & args) +CMD(changed, "", "list", "", + N_("Lists files that have changed with respect to the current revision"), + N_(""), + options::opts::depth | options::opts::exclude) { parent_map parents; roster_t new_roster; @@ -476,58 +497,14 @@ ls_changed(app_state & app, vector } +CMD_GROUP(list, "ls", "informative", + N_("Shows database objects"), + N_("This command is used to query information from the database. " + "It shows database objects, or the current workspace manifest, " + "or known, unknown, intentionally ignored, missing, or " + "changed-state files."), + options::opts::none); -CMD(list, "ls", N_("informative"), - N_("certs ID\n" - "keys [PATTERN]\n" - "branches [PATTERN]\n" - "epochs [BRANCH [...]]\n" - "tags\n" - "vars [DOMAIN]\n" - "known\n" - "unknown\n" - "ignored\n" - "missing\n" - "changed"), - N_("Shows database objects"), - N_("Shows database objects, or the current workspace manifest, " - "or known, unknown, intentionally ignored, missing, or " - "changed-state files."), - options::opts::depth | options::opts::exclude) -{ - if (args.size() == 0) - throw usage(name); - - vector::const_iterator i = args.begin(); - ++i; - vector removed (i, args.end()); - if (idx(args, 0)() == "certs") - ls_certs(name, app, removed); - else if (idx(args, 0)() == "keys") - ls_keys(name, app, removed); - else if (idx(args, 0)() == "branches") - ls_branches(name, app, removed); - else if (idx(args, 0)() == "epochs") - ls_epochs(name, app, removed); - else if (idx(args, 0)() == "tags") - ls_tags(name, app, removed); - else if (idx(args, 0)() == "vars") - ls_vars(name, app, removed); - else if (idx(args, 0)() == "known") - ls_known(app, removed); - else if (idx(args, 0)() == "unknown") - ls_unknown_or_ignored(app, false, removed); - else if (idx(args, 0)() == "ignored") - ls_unknown_or_ignored(app, true, removed); - else if (idx(args, 0)() == "missing") - ls_missing(app, removed); - else if (idx(args, 0)() == "changed") - ls_changed(app, removed); - else - throw usage(name); -} - - namespace { namespace syms ============================================================ --- commands.cc d2caef21d0c131f5669e29d1228befd0469549ab +++ commands.cc 38463c25992cc776d9150992e6d31c27509c612b @@ -85,7 +85,7 @@ CMD_GROUP(tree, "", root_parent(), N_("Commands to manipulate the tree"), N_(""), options::opts::none); -CMD_GROUP(vars, "", root_parent(), +CMD_GROUP(variables, "", root_parent(), N_("Commands to manage persistent variables"), N_(""), options::opts::none); @@ -199,12 +199,31 @@ namespace commands && (string(_(selfname.c_str())) < (string(_(othername.c_str())))))); } + // XXX Remove this one. static command * find_command(string const & name) { map< string, command * >::iterator iter = (*cmds).find(name); return iter == (*cmds).end() ? NULL : (*iter).second; } + command * find_command(command const * startcmd, string const & name) + { + for (set< command * >::iterator iter = startcmd->children.begin(); + iter != startcmd->children.end(); iter++) + { + command * child = *iter; + + for (set< string >::const_iterator iter2 = child->names.begin(); + iter2 != child->names.end(); iter2++) + { + if (*iter2 == name) + return child; + } + } + + return NULL; + } + static void init_children(void) { static bool children_inited = false;