# # # patch "asciik.cc" # from [a4d7d66878035a99c7a0424f4d4cc91318fe2ba4] # to [c93f8aa68de5fdde236d1d6ca82924e6aad33f93] # # patch "cmd.hh" # from [3cb17398a31af4acc7c785e2f7efbbbe3a14c274] # to [aa8269c18d97811748737eea49e264742e81bc94] # # patch "cmd_automate.cc" # from [b051e7231aabf55de2e33d19379e7051d6fa72d1] # to [21cb7f86d4fc6e33e3f6346bc16521f4317bbe4f] # # patch "cmd_db.cc" # from [639d701a732f7b2f43ffade40fb3b3c966f92292] # to [f573927bdfc3dd47c534f36e69ad7c700a44e154] # # patch "cmd_diff_log.cc" # from [65cc2380294983ba6e095247d434dbbd8883b898] # to [5822504cb86d441755b7b3e29dd7802f32985e86] # # patch "cmd_files.cc" # from [b3e0ca1cb55a38fbbf8cb631ae267032742f326f] # to [929ca87b0e12c5127f70e01d8f4d1c43d5de294c] # # patch "cmd_key_cert.cc" # from [41ec84001fbc2ad415128b1635a426317c56553e] # to [ee6de8d946fe1205c3857eb6eebbd399b1efef92] # # patch "cmd_list.cc" # from [72e73a38bcb76a30f62a556d367b35f817eab8fb] # to [93eee2d3af29db17a6b63805b00c35b34a508306] # # patch "cmd_merging.cc" # from [6e93678185ed13e3b17a1297caa6cf8bb88d5632] # to [253ec239c75a1acb480398447547d7e346463636] # # patch "cmd_netsync.cc" # from [9b1d9738ce80949189304e0e3b31d3d7dc5f61b4] # to [112367df549e8baf0dbbb5e62684b6b076093b07] # # patch "cmd_othervcs.cc" # from [4b7b092cc8a3aecc134727a10242958fcd97d651] # to [9150351d7bd8029429f505f1d08ef5775b80910b] # # patch "cmd_packet.cc" # from [d5146cb4d1118fad790c772741ceda7a055f8bf3] # to [03af44ce9be22d3d6b1011eea767c8f761b1deaf] # # patch "cmd_ws_commit.cc" # from [8402e317a9f920469babbae15748cde3dc5f9bfa] # to [bf08400c71b6b82ba071b6c4e4033dcad240ab85] # # patch "commands.cc" # from [52ac43cdc4493760010eb0a05e4d27eca3887ebb] # to [685ea533bef8ffca6be67b776347fcf19e59563d] # # patch "revision.cc" # from [e7ebc4012c20018b4b583e22eb3299d33113b862] # to [7c2a9fc44fab22eaf5166ac846d96400cf44e872] # # patch "sha1.cc" # from [98c1df304ae062bdbf2157f023ce31595191fb02] # to [2417f83de1b98aacb1850b4d3e5221cf40a13cdf] # ============================================================ --- asciik.cc a4d7d66878035a99c7a0424f4d4cc91318fe2ba4 +++ asciik.cc c93f8aa68de5fdde236d1d6ca82924e6aad33f93 @@ -365,7 +365,7 @@ asciik::print(revision_id const & rev, } } -CMD(asciik, N_("debug"), N_("SELECTOR"), +CMD(asciik, "", N_("debug"), N_("SELECTOR"), N_("Prints an ASCII representation of the revisions' graph"), N_(""), options::opts::none) ============================================================ --- cmd.hh 3cb17398a31af4acc7c785e2f7efbbbe3a14c274 +++ cmd.hh aa8269c18d97811748737eea49e264742e81bc94 @@ -29,7 +29,7 @@ namespace commands // NB: these strings are stored _un_translated, because we cannot // translate them until after main starts, by which time the // command objects have all been constructed. - std::string name; + std::set< std::string > names; std::string cmdgroup; std::string params_; std::string abstract_; @@ -37,6 +37,7 @@ namespace commands bool use_workspace_options; options::options_type opts; command(std::string const & n, + std::string const & aliases, std::string const & g, std::string const & p, std::string const & a, @@ -49,14 +50,9 @@ namespace commands virtual std::string desc(); virtual options::options_type get_options(std::vector const & args); virtual void exec(app_state & app, + std::string const & name, std::vector const & args) = 0; }; - - // This type and global map maintain a relation between each command name - // and all of its aliases. If the command has no aliases, it is not - // present here. - typedef std::map< std::string, std::set > aliases_map; - extern aliases_map aliases; }; inline std::vector @@ -105,32 +101,36 @@ process_commit_message_args(bool & given app_state & app, utf8 message_prefix = utf8("")); -#define CMD(C, group, params, abstract, desc, opts) \ +#define CMD(C, aliases, group, params, abstract, desc, opts) \ namespace commands { \ struct cmd_ ## C : public command \ { \ - cmd_ ## C() : command(#C, group, params, abstract, desc, true, \ + cmd_ ## C() : command(#C, aliases, group, params, abstract, \ + desc, true, \ options::options_type() | opts) \ {} \ virtual void exec(app_state & app, \ + std::string const & name, \ std::vector const & args); \ }; \ static cmd_ ## C C ## _cmd; \ } \ void commands::cmd_ ## C::exec(app_state & app, \ + std::string const & name, \ std::vector const & args) // Use this for commands that want to define a params() function // instead of having a static description. (Good for "automate" // and possibly "list".) -#define CMD_WITH_SUBCMDS(C, group, abstract, desc, opts) \ +#define CMD_WITH_SUBCMDS(C, aliases, group, abstract, desc, opts) \ namespace commands { \ struct cmd_ ## C : public command \ { \ - cmd_ ## C() : command(#C, group, "", abstract, desc, true, \ - options::options_type() | opts) \ + cmd_ ## C() : command(#C, aliases, group, "", abstract, desc, \ + true, options::options_type() | opts) \ {} \ virtual void exec(app_state & app, \ + std::string const & name, \ std::vector const & args); \ std::string params(); \ options::options_type get_options(vector const & args); \ @@ -138,68 +138,30 @@ void commands::cmd_ ## C::exec(app_state static cmd_ ## C C ## _cmd; \ } \ void commands::cmd_ ## C::exec(app_state & app, \ + std::string const & name, \ std::vector const & args) // Use this for commands that should specifically _not_ look for an // _MTN dir and load options from it. -#define CMD_NO_WORKSPACE(C, group, params, abstract, desc, opts) \ +#define CMD_NO_WORKSPACE(C, aliases, group, params, abstract, desc, opts) \ namespace commands { \ struct cmd_ ## C : public command \ { \ - cmd_ ## C() : command(#C, group, params, abstract, desc, false, \ + cmd_ ## C() : command(#C, aliases, group, params, abstract, \ + desc, false, \ options::options_type() | opts) \ {} \ virtual void exec(app_state & app, \ + std::string const & name, \ std::vector const & args); \ }; \ static cmd_ ## C C ## _cmd; \ } \ void commands::cmd_ ## C::exec(app_state & app, \ + std::string const & name, \ std::vector const & args) \ -#define ALIAS(C, realcommand) \ -namespace commands { \ - struct cmd_ ## C : public command \ - { \ - cmd_ ## C() : command(#C, realcommand##_cmd.cmdgroup, \ - realcommand##_cmd.params_, \ - realcommand##_cmd.abstract_, \ - realcommand##_cmd.desc_, true, \ - realcommand##_cmd.opts) \ - { \ - aliases_map::iterator i = aliases.find(#realcommand); \ - if (i == aliases.end()) \ - { \ - std::set as; \ - as.insert(#C); \ - aliases.insert(aliases_map::value_type(#realcommand, as)); \ - } \ - else \ - { \ - std::set & as = (*i).second; \ - as.insert(#C); \ - } \ - } \ - virtual std::string desc(); \ - virtual void exec(app_state & app, \ - std::vector const & args); \ - }; \ - static cmd_ ## C C ## _cmd; \ -} \ -std::string commands::cmd_ ## C::desc() \ -{ \ - std::string result = abstract() + ".\n" + _(desc_.c_str()); \ - result += "\n"; \ - result += (F("Alias for %s.") % #realcommand).str(); \ - return result; \ -} \ -void commands::cmd_ ## C::exec(app_state & app, \ - std::vector const & args) \ -{ \ - process(app, std::string(#realcommand), args); \ -} - namespace automation { struct automate { ============================================================ --- cmd_automate.cc b051e7231aabf55de2e33d19379e7051d6fa72d1 +++ cmd_automate.cc 21cb7f86d4fc6e33e3f6346bc16521f4317bbe4f @@ -374,7 +374,7 @@ AUTOMATE(stdio, "", options::opts::autom } -CMD_WITH_SUBCMDS(automate, N_("automation"), +CMD_WITH_SUBCMDS(automate, "", N_("automation"), N_("Interface for scripted execution"), N_("This set of commands provides a stable interface to run " "monotone from other, external tools and interact with it " ============================================================ --- cmd_db.cc 639d701a732f7b2f43ffade40fb3b3c966f92292 +++ cmd_db.cc f573927bdfc3dd47c534f36e69ad7c700a44e154 @@ -45,7 +45,7 @@ kill_rev_locally(app_state& app, string app.db.delete_existing_rev_and_certs(ident); } -CMD(db, N_("database"), +CMD(db, "", N_("database"), N_("init\n" "info\n" "version\n" @@ -123,7 +123,7 @@ CMD(db, N_("database"), throw usage(name); } -CMD(set, N_("vars"), N_("DOMAIN NAME VALUE"), +CMD(set, "", N_("vars"), N_("DOMAIN NAME VALUE"), N_("Sets a database variable"), N_("This command modifies (or adds if it did not exist before) the " "variable named NAME, stored in the database, and sets it to the " @@ -142,7 +142,7 @@ CMD(set, N_("vars"), N_("DOMAIN NAME VAL app.db.set_var(make_pair(d, n), v); } -CMD(unset, N_("vars"), N_("DOMAIN NAME"), +CMD(unset, "", N_("vars"), N_("DOMAIN NAME"), N_("Unsets a database variable"), N_("This command removes the variable NAME from domain DOMAIN, which" "was previously stored in the database."), @@ -161,7 +161,7 @@ CMD(unset, N_("vars"), N_("DOMAIN NAME") app.db.clear_var(k); } -CMD(complete, N_("informative"), N_("(revision|file|key) PARTIAL-ID"), +CMD(complete, "", N_("informative"), N_("(revision|file|key) PARTIAL-ID"), N_("Completes a partial identifier"), N_(""), options::opts::verbose) @@ -210,7 +210,7 @@ CMD(complete, N_("informative"), N_("(re throw usage(name); } -CMD(test_migration_step, hidden_group(), "SCHEMA", +CMD(test_migration_step, "", hidden_group(), "SCHEMA", N_("Runs one step of migration on the specified database"), N_("This command migrates the given database from the specified schema " "in SCHEMA to its successor."), ============================================================ --- cmd_diff_log.cc 65cc2380294983ba6e095247d434dbbd8883b898 +++ cmd_diff_log.cc 5822504cb86d441755b7b3e29dd7802f32985e86 @@ -468,7 +468,7 @@ prepare_diff(cset & included, revheader = header.str(); } -CMD(diff, N_("informative"), N_("[PATH]..."), +CMD(diff, "", N_("informative"), N_("[PATH]..."), N_("Shows current differences"), N_("Compares the current tree with the files in the repository and " "prints the differences on the standard output.\n" @@ -600,7 +600,7 @@ typedef priority_queue >, rev_cmp> frontier_t; -CMD(log, N_("informative"), N_("[FILE] ..."), +CMD(log, "", N_("informative"), N_("[FILE] ..."), N_("Prints history in reverse order"), N_("This command prints history in reverse order, filtering it by " "FILE if given. If one or more revisions are given, uses them as " ============================================================ --- cmd_files.cc b3e0ca1cb55a38fbbf8cb631ae267032742f326f +++ cmd_files.cc 929ca87b0e12c5127f70e01d8f4d1c43d5de294c @@ -26,7 +26,7 @@ using std::vector; // fload, fmerge, and fdiff are simple commands for debugging the line // merger. -CMD(fload, N_("debug"), "", +CMD(fload, "", N_("debug"), "", N_("Loads a file's contents into the database"), N_(""), options::opts::none) @@ -44,7 +44,7 @@ CMD(fload, N_("debug"), "", guard.commit(); } -CMD(fmerge, N_("debug"), N_(" "), +CMD(fmerge, "", N_("debug"), N_(" "), N_("Merges 3 files and outputs the result"), N_(""), options::opts::none) @@ -82,7 +82,7 @@ CMD(fmerge, N_("debug"), N_(" content); } -CMD(cat, N_("informative"), +CMD(cat, "", N_("informative"), N_("FILENAME"), N_("Prints a file from the database"), N_("Fetches the given file FILENAME from the database and prints it " ============================================================ --- cmd_key_cert.cc 41ec84001fbc2ad415128b1635a426317c56553e +++ cmd_key_cert.cc ee6de8d946fe1205c3857eb6eebbd399b1efef92 @@ -29,7 +29,7 @@ using Botan::RSA_PrivateKey; using Botan::Pipe; using Botan::RSA_PrivateKey; -CMD(genkey, N_("key and cert"), N_("KEYID"), +CMD(genkey, "", N_("key and cert"), N_("KEYID"), N_("Generates an RSA key-pair"), N_(""), options::opts::none) @@ -57,7 +57,7 @@ CMD(genkey, N_("key and cert"), N_("KEYI app.keys.put_key_pair(ident, kp); } -CMD(dropkey, N_("key and cert"), N_("KEYID"), +CMD(dropkey, "", N_("key and cert"), N_("KEYID"), N_("Drops a public and/or private key"), N_(""), options::opts::none) @@ -99,7 +99,7 @@ CMD(dropkey, N_("key and cert"), N_("KEY N(key_deleted, fmt % idx(args, 0)()); } -CMD(passphrase, N_("key and cert"), N_("KEYID"), +CMD(passphrase, "", N_("key and cert"), N_("KEYID"), N_("Changes the passphrase of a private RSA key"), N_(""), options::opts::none) @@ -121,7 +121,7 @@ CMD(passphrase, N_("key and cert"), N_(" P(F("passphrase changed")); } -CMD(ssh_agent_export, N_("key and cert"), +CMD(ssh_agent_export, "", N_("key and cert"), N_("[FILENAME]"), N_("Exports a private key for use with ssh-agent"), N_(""), @@ -161,7 +161,7 @@ CMD(ssh_agent_export, N_("key and cert") } } -CMD(ssh_agent_add, N_("key and cert"), "", +CMD(ssh_agent_add, "", N_("key and cert"), "", N_("Adds a private key to ssh-agent"), N_(""), options::opts::none) @@ -178,7 +178,7 @@ CMD(ssh_agent_add, N_("key and cert"), " app.agent.add_identity(*priv, id()); } -CMD(cert, N_("key and cert"), N_("REVISION CERTNAME [CERTVAL]"), +CMD(cert, "", N_("key and cert"), N_("REVISION CERTNAME [CERTVAL]"), N_("Creates a certificate for a revision"), N_(""), options::opts::none) @@ -191,8 +191,8 @@ CMD(cert, N_("key and cert"), N_("REVISI revision_id rid; complete(app, idx(args, 0)(), rid); - cert_name name; - internalize_cert_name(idx(args, 1), name); + cert_name cname; + internalize_cert_name(idx(args, 1), cname); rsa_keypair_id key; get_user_key(key, app); @@ -207,11 +207,11 @@ CMD(cert, N_("key and cert"), N_("REVISI val = cert_value(dat()); } - app.get_project().put_cert(rid, name, val); + app.get_project().put_cert(rid, cname, val); guard.commit(); } -CMD(trusted, N_("key and cert"), +CMD(trusted, "", N_("key and cert"), N_("REVISION NAME VALUE SIGNER1 [SIGNER2 [...]]"), N_("Tests whether a hypothetical certificate would be trusted"), N_("The current settings are used to run the test."), @@ -224,8 +224,8 @@ CMD(trusted, N_("key and cert"), complete(app, idx(args, 0)(), rid, false); hexenc ident(rid.inner()); - cert_name name; - internalize_cert_name(idx(args, 1), name); + cert_name cname; + internalize_cert_name(idx(args, 1), cname); cert_value value(idx(args, 2)()); @@ -239,7 +239,7 @@ CMD(trusted, N_("key and cert"), bool trusted = app.lua.hook_get_revision_cert_trust(signers, ident, - name, value); + cname, value); ostringstream all_signers; @@ -252,14 +252,14 @@ CMD(trusted, N_("key and cert"), "was signed by: %s\n" "it would be: %s") % ident - % name + % cname % value % all_signers.str() % (trusted ? _("trusted") : _("UNtrusted"))) << '\n'; // final newline is kept out of the translation } -CMD(tag, N_("review"), N_("REVISION TAGNAME"), +CMD(tag, "", N_("review"), N_("REVISION TAGNAME"), N_("Puts a symbolic tag certificate on a revision"), N_(""), options::opts::none) @@ -273,7 +273,7 @@ CMD(tag, N_("review"), N_("REVISION TAGN } -CMD(testresult, N_("review"), N_("ID (pass|fail|true|false|yes|no|1|0)"), +CMD(testresult, "", N_("review"), N_("ID (pass|fail|true|false|yes|no|1|0)"), N_("Notes the results of running a test on a revision"), N_(""), options::opts::none) @@ -287,7 +287,7 @@ CMD(testresult, N_("review"), N_("ID (pa } -CMD(approve, N_("review"), N_("REVISION"), +CMD(approve, "", N_("review"), N_("REVISION"), N_("Approves a particular revision"), N_(""), options::opts::branch) @@ -302,7 +302,7 @@ CMD(approve, N_("review"), N_("REVISION" app.get_project().put_revision_in_branch(r, app.opts.branchname); } -CMD(comment, N_("review"), N_("REVISION [COMMENT]"), +CMD(comment, "", N_("review"), N_("REVISION [COMMENT]"), N_("Comments on a particular revision"), N_(""), options::opts::none) ============================================================ --- cmd_list.cc 72e73a38bcb76a30f62a556d367b35f817eab8fb +++ cmd_list.cc 93eee2d3af29db17a6b63805b00c35b34a508306 @@ -477,7 +477,7 @@ ls_changed(app_state & app, vector } -CMD(list, N_("informative"), +CMD(list, "ls", N_("informative"), N_("certs ID\n" "keys [PATTERN]\n" "branches [PATTERN]\n" @@ -527,7 +527,6 @@ CMD(list, N_("informative"), throw usage(name); } -ALIAS(ls, list); namespace { ============================================================ --- cmd_merging.cc 6e93678185ed13e3b17a1297caa6cf8bb88d5632 +++ cmd_merging.cc 253ec239c75a1acb480398447547d7e346463636 @@ -126,7 +126,7 @@ pick_branch_for_update(revision_id chose return switched_branch; } -CMD(update, N_("workspace"), "", +CMD(update, "", N_("workspace"), "", N_("Updates the workspace"), N_("This command modifies your workspace to be based off of a " "different revision, preserving uncommitted changes as it does so. " @@ -329,7 +329,7 @@ merge_two(revision_id const & left, revi // since a single 'merge' command may perform arbitrarily many actual merges. // (Possibility: append the --message/--message-file text to the synthetic // log message constructed in merge_two().) -CMD(merge, N_("tree"), "", +CMD(merge, "", N_("tree"), "", N_("Merges unmerged heads of a branch"), N_(""), options::opts::branch | options::opts::date | options::opts::author) @@ -430,7 +430,7 @@ CMD(merge, N_("tree"), "", P(F("note: your workspaces have not been updated")); } -CMD(propagate, N_("tree"), N_("SOURCE-BRANCH DEST-BRANCH"), +CMD(propagate, "", N_("tree"), N_("SOURCE-BRANCH DEST-BRANCH"), N_("Merges from one branch to another asymmetrically"), N_(""), options::opts::date | options::opts::author | options::opts::message | options::opts::msgfile) @@ -442,7 +442,7 @@ CMD(propagate, N_("tree"), N_("SOURCE-BR process(app, "merge_into_dir", a); } -CMD(merge_into_dir, N_("tree"), N_("SOURCE-BRANCH DEST-BRANCH DIR"), +CMD(merge_into_dir, "", N_("tree"), N_("SOURCE-BRANCH DEST-BRANCH DIR"), N_("Merges one branch into a subdirectory in another branch"), N_(""), options::opts::date | options::opts::author | options::opts::message | options::opts::msgfile) @@ -599,7 +599,7 @@ CMD(merge_into_dir, N_("tree"), N_("SOUR } } -CMD(merge_into_workspace, N_("tree"), +CMD(merge_into_workspace, "", N_("tree"), N_("OTHER-REVISION"), N_("Merges a revision into the current workspace's base revision"), N_("Merges OTHER-REVISION into the current workspace's base revision, " @@ -693,7 +693,7 @@ CMD(merge_into_workspace, N_("tree"), "[right] %s\n") % left_id % right_id); } -CMD(explicit_merge, N_("tree"), +CMD(explicit_merge, "", N_("tree"), N_("LEFT-REVISION RIGHT-REVISION DEST-BRANCH"), N_("Merges two explicitly given revisions"), N_("The results of the merge are placed on the branch specified by " @@ -720,7 +720,7 @@ CMD(explicit_merge, N_("tree"), merge_two(left, right, branch, string("explicit merge"), app); } -CMD(show_conflicts, N_("informative"), N_("REV REV"), +CMD(show_conflicts, "", N_("informative"), N_("REV REV"), N_("Shows what conflicts need resolution between two revisions"), N_("The conflicts are calculated based on the two revisions given in " "the REV parameters."), @@ -762,7 +762,7 @@ CMD(show_conflicts, N_("informative"), N % result.directory_loop_conflicts.size()); } -CMD(pluck, N_("workspace"), N_("[-r FROM] -r TO [PATH...]"), +CMD(pluck, "", N_("workspace"), N_("[-r FROM] -r TO [PATH...]"), N_("Applies changes made at arbitrary places in history"), N_("This command takes changes made at any point in history, and " "edits your current workspace to include those changes. The end result " @@ -929,7 +929,7 @@ CMD(pluck, N_("workspace"), N_("[-r FROM } } -CMD(heads, N_("tree"), "", +CMD(heads, "", N_("tree"), "", N_("Shows unmerged head revisions of a branch"), N_(""), options::opts::branch) @@ -955,7 +955,7 @@ CMD(heads, N_("tree"), "", cout << describe_revision(app, *i) << '\n'; } -CMD(get_roster, N_("debug"), N_("[REVID]"), +CMD(get_roster, "", N_("debug"), N_("[REVID]"), N_("Dumps the roster associated with a given identifier"), N_("If no REVID is given, the workspace is used."), options::opts::none) ============================================================ --- cmd_netsync.cc 9b1d9738ce80949189304e0e3b31d3d7dc5f61b4 +++ cmd_netsync.cc 112367df549e8baf0dbbb5e62684b6b076093b07 @@ -121,7 +121,7 @@ extract_patterns(vector const & ar } } -CMD(push, N_("network"), N_("[ADDRESS[:PORTNUMBER] [PATTERN ...]]"), +CMD(push, "", N_("network"), N_("[ADDRESS[:PORTNUMBER] [PATTERN ...]]"), N_("Pushes branches to a netsync server"), N_("This will push all branches that match the pattern given in PATTERN " "to the netsync server at the address ADDRESS."), @@ -138,7 +138,7 @@ CMD(push, N_("network"), N_("[ADDRESS[:P include_pattern, exclude_pattern, app); } -CMD(pull, N_("network"), N_("[ADDRESS[:PORTNUMBER] [PATTERN ...]]"), +CMD(pull, "", N_("network"), N_("[ADDRESS[:PORTNUMBER] [PATTERN ...]]"), N_("Pulls branches from a netsync server"), N_("This pulls all branches that match the pattern given in PATTERN " "from the netsync server at the address ADDRESS."), @@ -156,7 +156,7 @@ CMD(pull, N_("network"), N_("[ADDRESS[:P include_pattern, exclude_pattern, app); } -CMD(sync, N_("network"), N_("[ADDRESS[:PORTNUMBER] [PATTERN ...]]"), +CMD(sync, "", N_("network"), N_("[ADDRESS[:PORTNUMBER] [PATTERN ...]]"), N_("Synchronizes branches with a netsync server"), N_("This synchronizes branches that match the pattern given in PATTERN " "with the netsync server at the address ADDRESS."), @@ -200,7 +200,7 @@ private: system_path dir; }; -CMD(clone, N_("network"), N_("ADDRESS[:PORTNUMBER] [DIRECTORY]"), +CMD(clone, "", N_("network"), N_("ADDRESS[:PORTNUMBER] [DIRECTORY]"), N_("Checks out a revision from remote a database into a directory"), N_("If a revision is given, that's the one that will be checked out. " "Otherwise, it will be the head of the branch supplied. " @@ -387,7 +387,7 @@ private: system_path path; }; -CMD_NO_WORKSPACE(serve, N_("network"), "", +CMD_NO_WORKSPACE(serve, "", N_("network"), "", N_("Serves the database to connecting clients"), N_(""), options::opts::bind | options::opts::pidfile | ============================================================ --- cmd_othervcs.cc 4b7b092cc8a3aecc134727a10242958fcd97d651 +++ cmd_othervcs.cc 9150351d7bd8029429f505f1d08ef5775b80910b @@ -13,7 +13,7 @@ using std::vector; using std::vector; -CMD(rcs_import, N_("debug"), N_("RCSFILE..."), +CMD(rcs_import, "", N_("debug"), N_("RCSFILE..."), N_("Parses versions in RCS files"), N_("This command doesn't reconstruct or import revisions. " "You probably want to use cvs_import."), @@ -30,7 +30,7 @@ CMD(rcs_import, N_("debug"), N_("RCSFILE } -CMD(cvs_import, N_("rcs"), N_("CVSROOT"), +CMD(cvs_import, "", N_("rcs"), N_("CVSROOT"), N_("Imports all versions in a CVS repository"), N_(""), options::opts::branch) ============================================================ --- cmd_packet.cc d5146cb4d1118fad790c772741ceda7a055f8bf3 +++ cmd_packet.cc 03af44ce9be22d3d6b1011eea767c8f761b1deaf @@ -19,7 +19,7 @@ using std::vector; using std::istringstream; using std::vector; -CMD(pubkey, N_("packet i/o"), N_("ID"), +CMD(pubkey, "", N_("packet i/o"), N_("ID"), N_("Prints a public key packet"), N_(""), options::opts::none) @@ -49,7 +49,7 @@ CMD(pubkey, N_("packet i/o"), N_("ID"), pw.consume_public_key(ident, key); } -CMD(privkey, N_("packet i/o"), N_("ID"), +CMD(privkey, "", N_("packet i/o"), N_("ID"), N_("Prints a private key packet"), N_(""), options::opts::none) @@ -130,7 +130,7 @@ namespace } -CMD(read, N_("packet i/o"), "[FILE1 [FILE2 [...]]]", +CMD(read, "", N_("packet i/o"), "[FILE1 [FILE2 [...]]]", N_("Reads packets from files"), N_("If no files are provided, the standard input is used."), options::opts::none) ============================================================ --- cmd_ws_commit.cc 8402e317a9f920469babbae15748cde3dc5f9bfa +++ cmd_ws_commit.cc bf08400c71b6b82ba071b6c4e4033dcad240ab85 @@ -78,7 +78,7 @@ get_log_message_interactively(revision_t system_to_utf8(log_message_external, log_message); } -CMD(revert, N_("workspace"), N_("[PATH]..."), +CMD(revert, "", N_("workspace"), N_("[PATH]..."), N_("Reverts files and/or directories"), N_("In order to revert the entire workspace, specify \".\" as the " "file name."), @@ -210,7 +210,7 @@ CMD(revert, N_("workspace"), N_("[PATH]. app.work.maybe_update_inodeprints(); } -CMD(disapprove, N_("review"), N_("REVISION"), +CMD(disapprove, "", N_("review"), N_("REVISION"), N_("Disapproves a particular revision"), N_(""), options::opts::branch | options::opts::messages | options::opts::date | @@ -264,7 +264,7 @@ CMD(disapprove, N_("review"), N_("REVISI } } -CMD(mkdir, N_("workspace"), N_("[DIRECTORY...]"), +CMD(mkdir, "", N_("workspace"), N_("[DIRECTORY...]"), N_("Creates directories and adds them to the workspace"), N_(""), options::opts::no_ignore) @@ -309,7 +309,7 @@ CMD(mkdir, N_("workspace"), N_("[DIRECTO app.work.perform_additions(paths, false, true); } -CMD(add, N_("workspace"), N_("[PATH]..."), +CMD(add, "", N_("workspace"), N_("[PATH]..."), N_("Adds files to the workspace"), N_(""), options::opts::unknown | options::opts::no_ignore | @@ -343,7 +343,7 @@ CMD(add, N_("workspace"), N_("[PATH]..." app.work.perform_additions(paths, add_recursive, !app.opts.no_ignore); } -CMD(drop, N_("workspace"), N_("[PATH]..."), +CMD(drop, "rm", N_("workspace"), N_("[PATH]..."), N_("Drops files from the workspace"), N_(""), options::opts::bookkeep_only | options::opts::missing | options::opts::recursive) @@ -371,10 +371,8 @@ CMD(drop, N_("workspace"), N_("[PATH]... app.work.perform_deletions(paths, app.opts.recursive, app.opts.bookkeep_only); } -ALIAS(rm, drop); - -CMD(rename, N_("workspace"), +CMD(rename, "mv", N_("workspace"), N_("SRC DEST\n" "SRC1 [SRC2 [...]] DEST_DIR"), N_("Renames entries in the workspace"), @@ -397,10 +395,8 @@ CMD(rename, N_("workspace"), app.work.perform_rename(src_paths, dst_path, app.opts.bookkeep_only); } -ALIAS(mv, rename); - -CMD(pivot_root, N_("workspace"), N_("NEW_ROOT PUT_OLD"), +CMD(pivot_root, "", N_("workspace"), N_("NEW_ROOT PUT_OLD"), N_("Renames the root directory"), N_("After this command, the directory that currently " "has the name NEW_ROOT " @@ -419,7 +415,7 @@ CMD(pivot_root, N_("workspace"), N_("NEW app.work.perform_pivot_root(new_root, put_old, app.opts.bookkeep_only); } -CMD(status, N_("informative"), N_("[PATH]..."), +CMD(status, "", N_("informative"), N_("[PATH]..."), N_("Shows workspace's status information"), N_(""), options::opts::depth | options::opts::exclude) @@ -493,7 +489,7 @@ CMD(status, N_("informative"), N_("[PATH } } -CMD(checkout, N_("tree"), N_("[DIRECTORY]"), +CMD(checkout, "co", N_("tree"), N_("[DIRECTORY]"), N_("Checks out a revision from the database into a directory"), N_("If a revision is given, that's the one that will be checked out. " "Otherwise, it will be the head of the branch (given or implicit). " @@ -600,9 +596,7 @@ CMD(checkout, N_("tree"), N_("[DIRECTORY guard.commit(); } -ALIAS(co, checkout); - -CMD(attr, N_("workspace"), +CMD(attr, "", N_("workspace"), N_("set PATH ATTR VALUE\nget PATH [ATTR]\ndrop PATH [ATTR]"), N_("Manages file attributes"), N_("This command is used to set, get or drop file attributes."), @@ -704,7 +698,7 @@ CMD(attr, N_("workspace"), -CMD(commit, N_("workspace"), N_("[PATH]..."), +CMD(commit, "ci", N_("workspace"), N_("[PATH]..."), N_("Commits workspace changes to the database"), N_(""), options::opts::branch | options::opts::message | options::opts::msgfile @@ -951,10 +945,7 @@ CMD(commit, N_("workspace"), N_("[PATH]. } } -ALIAS(ci, commit); - - -CMD_NO_WORKSPACE(setup, N_("tree"), N_("[DIRECTORY]"), +CMD_NO_WORKSPACE(setup, "", N_("tree"), N_("[DIRECTORY]"), N_("Sets up a new workspace directory"), N_("If no directory is specified, uses the current directory."), options::opts::branch) @@ -978,7 +969,7 @@ CMD_NO_WORKSPACE(setup, N_("tree"), N_(" app.work.put_work_rev(rev); } -CMD_NO_WORKSPACE(import, N_("tree"), N_("DIRECTORY"), +CMD_NO_WORKSPACE(import, "", N_("tree"), N_("DIRECTORY"), N_("Imports the contents of a directory into a branch"), N_(""), options::opts::branch | options::opts::revision | @@ -1079,7 +1070,7 @@ CMD_NO_WORKSPACE(import, N_("tree"), N_( delete_dir_recursive(bookkeeping_root); } -CMD_NO_WORKSPACE(migrate_workspace, N_("tree"), N_("[DIRECTORY]"), +CMD_NO_WORKSPACE(migrate_workspace, "", N_("tree"), N_("[DIRECTORY]"), N_("Migrates a workspace directory's metadata to the latest format"), N_("If no directory is given, defaults to the current workspace."), options::opts::none) @@ -1093,7 +1084,7 @@ CMD_NO_WORKSPACE(migrate_workspace, N_(" app.work.migrate_ws_format(); } -CMD(refresh_inodeprints, N_("tree"), "", +CMD(refresh_inodeprints, "", N_("tree"), "", N_("Refreshes the inodeprint cache"), N_(""), options::opts::none) ============================================================ --- commands.cc 52ac43cdc4493760010eb0a05e4d27eca3887ebb +++ commands.cc 685ea533bef8ffca6be67b776347fcf19e59563d @@ -50,8 +50,6 @@ namespace commands namespace commands { - aliases_map aliases; - const char * safe_gettext(const char * msgid) { if (strlen(msgid) == 0) @@ -69,18 +67,30 @@ namespace commands // it ourselves the first time we use it. static map * cmds; command::command(string const & n, + string const & aliases, string const & g, string const & p, string const & a, string const & d, bool u, options::options_type const & o) - : name(n), cmdgroup(g), params_(p), abstract_(a), desc_(d), + : cmdgroup(g), params_(p), abstract_(a), desc_(d), use_workspace_options(u), opts(o) { if (cmds == NULL) - cmds = new map; + cmds = new map< string, command * >; + + names.insert(n); (*cmds)[n] = this; + + std::vector< std::string > as; + split_into_words(aliases, as); + for (std::vector< std::string >::const_iterator iter = as.begin(); + iter != as.end(); iter++) + { + names.insert(*iter); + (*cmds)[*iter] = this; + } } command::~command() {} std::string command::params() {return safe_gettext(params_.c_str());} @@ -148,43 +158,39 @@ namespace commands bool operator<(command const & self, command const & other) { + // These two get the "minor" names of each command, as the 'names' + // set is sorted alphabetically. + string const & selfname = *(self.names.begin()); + string const & othername = *(other.names.begin()); // *twitch* return ((string(_(self.cmdgroup.c_str())) < string(_(other.cmdgroup.c_str()))) || ((self.cmdgroup == other.cmdgroup) - && (string(_(self.name.c_str())) < (string(_(other.name.c_str())))))); + && (string(_(selfname.c_str())) < (string(_(othername.c_str())))))); } - static bool is_alias(string const & cmd) - { - bool ia = false; - - if (aliases.find(cmd) == aliases.end()) - for (aliases_map::const_iterator iter = aliases.begin(); - iter != aliases.end() && !ia; iter++) - { - set const & as = (*iter).second; - if (as.find(cmd) != as.end()) - ia = true; - } - - return ia; - } - string complete_command(string const & cmd) { if (cmd.length() == 0 || (*cmds).find(cmd) != (*cmds).end()) return cmd; L(FL("expanding command '%s'") % cmd); - vector matched; + set matched; for (map::const_iterator i = (*cmds).begin(); i != (*cmds).end(); ++i) { - if (cmd.length() < i->first.length()) + set< string > const & names = i->second->names; + + for (set< string >::const_iterator i2 = names.begin(); + i2 != names.end(); i2++) { - string prefix(i->first, 0, cmd.length()); - if (cmd == prefix) matched.push_back(i->first); + string const & name = *i2; + + if (cmd.length() < name.length()) + { + string prefix(name, 0, cmd.length()); + if (cmd == prefix) matched.insert(name); + } } } @@ -202,7 +208,7 @@ namespace commands // more than one matched command string err = (F("command '%s' has multiple ambiguous expansions:") % cmd).str(); - for (vector::iterator i = matched.begin(); + for (set::iterator i = matched.begin(); i != matched.end(); ++i) err += ('\n' + *i); W(i18n_format(err)); @@ -258,28 +264,19 @@ namespace commands // for simplicity reasons later on, where a1 through aN are the aliases // for the command cmd. Returns the empty string if no aliases are // defined for that command. - static string format_aliases(string const & cmd) + static string format_names(set< string > const & names) { string text; - aliases_map::const_iterator iter = aliases.find(cmd); - if (iter != aliases.end()) + set< string >::const_iterator iter = names.begin(); + do { - text = " ("; - - set const & as = (*iter).second; - set::const_iterator asiter = as.begin(); - for (;;) - { - text += *asiter; - asiter++; - if (asiter == as.end()) - break; - text += ", "; - } - - text += ")"; + text += *iter; + iter++; + if (iter != names.end()) + text += ", "; } + while (iter != names.end()); return text; } @@ -391,13 +388,11 @@ namespace commands for (map::const_iterator i = (*cmds).begin(); i != (*cmds).end(); ++i) { - const string & name = i->second->name; - - if (i->second->cmdgroup == cmdgroup && !is_alias(name)) + if (i->second->cmdgroup == cmdgroup) { sorted.push_back(i->second); - string tag = name + format_aliases(name); + string tag = format_names(i->second->names); size_t len = display_width(utf8(tag + " ")); if (colabstract < len) colabstract = len; @@ -409,10 +404,10 @@ namespace commands out << (*grpi).second << ":" << std::endl; for (size_t i = 0; i < sorted.size(); ++i) { - string const & name = idx(sorted, i)->name; + set< string > const & names = idx(sorted, i)->names; string const & abstract = idx(sorted, i)->abstract(); - string tag = name + format_aliases(name); + string tag = format_names(names); describe(tag, abstract, colabstract, out); } } @@ -431,7 +426,7 @@ namespace commands split_into_lines(params, lines); for (vector::const_iterator j = lines.begin(); j != lines.end(); ++j) - out << " " << i->second->name << ' ' << *j << std::endl; + out << " " << cmd << ' ' << *j << std::endl; split_into_lines(i->second->desc(), lines); for (vector::const_iterator j = lines.begin(); j != lines.end(); ++j) @@ -439,6 +434,13 @@ namespace commands describe("", *j, 4, out); out << std::endl; } + if (i->second->names.size() > 1) + { + set< string > othernames = i->second->names; + othernames.erase(cmd); + describe("", "Aliases: " + format_names(othernames) + ".", 4, out); + out << std::endl; + } } void explain_usage(string const & cmd, ostream & out) @@ -486,7 +488,7 @@ namespace commands if ((*cmds)[cmd]->use_workspace_options) app.process_options(); - (*cmds)[cmd]->exec(app, args); + (*cmds)[cmd]->exec(app, cmd, args); return 0; } else @@ -501,7 +503,7 @@ namespace commands if (cmdline.empty()) return options::options_type(); string cmd = complete_command(idx(cmdline,0)()); - if ((*cmds).find(cmd) != (*cmds).end()) + if (!cmd.empty()) { return (*cmds)[cmd]->get_options(cmdline); } @@ -527,7 +529,7 @@ namespace commands } //////////////////////////////////////////////////////////////////////// -CMD(help, N_("informative"), N_("command [ARGS...]"), +CMD(help, "", N_("informative"), N_("command [ARGS...]"), N_("Displays help about commands and options"), N_(""), options::opts::none) @@ -560,7 +562,7 @@ CMD(help, N_("informative"), N_("command } } -CMD(crash, hidden_group(), "{ N | E | I | exception | signal }", +CMD(crash, "", hidden_group(), "{ N | E | I | exception | signal }", N_("Triggers the specified kind of crash"), N_(""), options::opts::none) @@ -773,50 +775,36 @@ process_commit_message_args(bool & given #ifdef BUILD_UNIT_TESTS #include "unit_tests.hh" -CMD(__test1, hidden_group(), "", "", "", options::opts::none) {} +CMD(__test1, "", hidden_group(), "", "", "", options::opts::none) {} -CMD(__test2, hidden_group(), "", "", "", options::opts::none) {} -ALIAS(__test2_alias1, __test2) +CMD(__test2, "__test2.1", + hidden_group(), "", "", "", options::opts::none) {} -CMD(__test3, hidden_group(), "", "", "", options::opts::none) {} -ALIAS(__test3_alias1, __test3) -ALIAS(__test3_alias2, __test3) +CMD(__test3, "__test3.1 __test3.2", + hidden_group(), "", "", "", options::opts::none) {} -UNIT_TEST(commands, is_alias) +UNIT_TEST(commands, format_names) { using namespace commands; - // Non-existent command. - BOOST_CHECK(!is_alias("__test0")); + // Command with one name. + BOOST_CHECK(format_names((*cmds)["__test1"]->names) == + "__test1"); - // Non-alias commands. - BOOST_CHECK(!is_alias("__test1")); - BOOST_CHECK(!is_alias("__test2")); - BOOST_CHECK(!is_alias("__test3")); + // Command with two names. + BOOST_CHECK(format_names((*cmds)["__test2"]->names) == + "__test2, __test2.1"); + BOOST_CHECK(format_names((*cmds)["__test2.1"]->names) == + "__test2, __test2.1"); - // Alias commands. - BOOST_CHECK(is_alias("__test2_alias1")); - BOOST_CHECK(is_alias("__test3_alias1")); - BOOST_CHECK(is_alias("__test3_alias2")); + // Command with three names. + BOOST_CHECK(format_names((*cmds)["__test3"]->names) == + "__test3, __test3.1, __test3.2"); + BOOST_CHECK(format_names((*cmds)["__test3.1"]->names) == + "__test3, __test3.1, __test3.2"); + BOOST_CHECK(format_names((*cmds)["__test3.2"]->names) == + "__test3, __test3.1, __test3.2"); } - -UNIT_TEST(commands, format_aliases) -{ - using namespace commands; - - // Non-existent command. - BOOST_CHECK(format_aliases("__test0").empty()); - - // Commands with aliases. - BOOST_CHECK(format_aliases("__test1").empty()); - BOOST_CHECK(format_aliases("__test2") == " (__test2_alias1)"); - BOOST_CHECK(format_aliases("__test3") == " (__test3_alias1, __test3_alias2)"); - - // Alias commands; cannot get their aliases. - BOOST_CHECK(format_aliases("__test2_alias1").empty()); - BOOST_CHECK(format_aliases("__test3_alias1").empty()); - BOOST_CHECK(format_aliases("__test3_alias2").empty()); -} #endif // BUILD_UNIT_TESTS // Local Variables: ============================================================ --- revision.cc e7ebc4012c20018b4b583e22eb3299d33113b862 +++ revision.cc 7c2a9fc44fab22eaf5166ac846d96400cf44e872 @@ -1804,7 +1804,7 @@ regenerate_caches(app_state & app) P(F("finished regenerating cached rosters and heights")); } -CMD(rev_height, hidden_group(), N_("REV"), +CMD(rev_height, "", hidden_group(), N_("REV"), N_("Shows a revision's height"), N_(""), options::opts::none) ============================================================ --- sha1.cc 98c1df304ae062bdbf2157f023ce31595191fb02 +++ sha1.cc 2417f83de1b98aacb1850b4d3e5221cf40a13cdf @@ -92,7 +92,7 @@ void hook_botan_sha1() Botan::global_state().add_engine(new Monotone_SHA1_Engine); } -CMD(benchmark_sha1, hidden_group(), "", +CMD(benchmark_sha1, "", hidden_group(), "", N_("Benchmarks SHA-1 cores"), N_(""), options::opts::none)