# HG changeset patch # User Florian Pose # Date 1216726701 0 # Node ID 9976f7b9fe663d4a0b7215946ab9d98734651290 # Parent 5da7c73c4f63e6fdc1320bd8daecd97d199490f6 Command abbreviation. diff -r 5da7c73c4f63 -r 9976f7b9fe66 tool/cmd_alias.cpp --- a/tool/cmd_alias.cpp Tue Jul 22 09:03:10 2008 +0000 +++ b/tool/cmd_alias.cpp Tue Jul 22 11:38:21 2008 +0000 @@ -47,7 +47,7 @@ unsigned int numSlaves, i; if (commandArgs.size() != 1) { - err << "'" << command << "' takes exactly one argument!"; + err << "'" << commandName << "' takes exactly one argument!"; throw InvalidUsageException(err); } diff -r 5da7c73c4f63 -r 9976f7b9fe66 tool/globals.h --- a/tool/globals.h Tue Jul 22 09:03:10 2008 +0000 +++ b/tool/globals.h Tue Jul 22 11:38:21 2008 +0000 @@ -21,7 +21,7 @@ Verbose }; -extern string command; +extern string commandName; extern int slavePosition; extern int domainIndex; extern vector commandArgs; diff -r 5da7c73c4f63 -r 9976f7b9fe66 tool/main.cpp --- a/tool/main.cpp Tue Jul 22 09:03:10 2008 +0000 +++ b/tool/main.cpp Tue Jul 22 11:38:21 2008 +0000 @@ -20,7 +20,7 @@ unsigned int masterIndex = 0; int slavePosition = -1; int domainIndex = -1; -string command; +string commandName; vector commandArgs; Verbosity verbosity = Normal; string dataTypeStr; @@ -33,6 +33,7 @@ /*****************************************************************************/ struct Command { + const char *name; void (*func)(void); const char *helpString; @@ -40,27 +41,20 @@ void displayHelp(void) const; }; -struct CommandAlias { - const char *name; - const Command *command; -}; - /*****************************************************************************/ #define COMMAND(name) \ void command_##name(void); \ - extern const char *help_##name; \ - const Command cmd_##name = {command_##name, help_##name}; + extern const char *help_##name + +#define INIT_COMMAND(name) {#name, command_##name, help_##name} COMMAND(alias); COMMAND(config); -const CommandAlias commandAliases[] = { - {"alias", &cmd_alias}, - - {"config", &cmd_config}, - {"conf", &cmd_config}, - {"cf", &cmd_config}, +static const Command commands[] = { + INIT_COMMAND(alias), + INIT_COMMAND(config), }; #if 0 @@ -115,6 +109,7 @@ << " slaves Show slaves." << endl << " state Request slave states." << endl << " xml Generate slave information xmls." << endl + << "Commands can be generously abbreviated." << endl << "Global options:" << endl << " --master -m Index of the master to use. Default: 0" << endl @@ -241,7 +236,7 @@ exit(!helpRequested); } - command = argv[optind]; + commandName = argv[optind]; while (++optind < argc) commandArgs.push_back(string(argv[optind])); } @@ -271,7 +266,41 @@ void Command::displayHelp() const { - cerr << binaryBaseName << " " << command << " " << helpString; + cerr << binaryBaseName << " " << commandName << " " << helpString; +} + +/****************************************************************************/ + +bool abbrevMatch(const string &abb, const string &full) +{ + unsigned int abbIndex; + size_t fullPos = 0; + + for (abbIndex = 0; abbIndex < abb.length(); abbIndex++) { + fullPos = full.find(abb[abbIndex], fullPos); + if (fullPos == string::npos) + return false; + } + + return true; +} + +/****************************************************************************/ + +list getMatchingCommands(const string &cmdStr) +{ + const Command *cmd, *endCmd = + commands + sizeof(commands) / sizeof(Command); + list res; + + // find matching commands + for (cmd = commands; cmd < endCmd; cmd++) { + if (abbrevMatch(cmdStr, cmd->name)) { + res.push_back(cmd); + } + } + + return res; } /****************************************************************************/ @@ -279,28 +308,35 @@ int main(int argc, char **argv) { int retval = 0; - const CommandAlias *alias; - const CommandAlias *endAlias = - commandAliases + sizeof(commandAliases) / sizeof(CommandAlias); + list commands; + list::const_iterator ci; + const Command *cmd; binaryBaseName = basename(argv[0]); getOptions(argc, argv); - // search command alias in alias map - for (alias = commandAliases; alias < endAlias; alias++) { - if (command == alias->name) - break; - } - - if (alias < endAlias) { // command alias found - if (!helpRequested) { - masterDev.setIndex(masterIndex); - retval = alias->command->execute(); + commands = getMatchingCommands(commandName); + + if (commands.size()) { + if (commands.size() == 1) { + cmd = commands.front(); + if (!helpRequested) { + masterDev.setIndex(masterIndex); + retval = cmd->execute(); + } else { + cmd->displayHelp(); + } } else { - alias->command->displayHelp(); + cerr << "Ambigous command abbreviation! Matching:" << endl; + for (ci = commands.begin(); ci != commands.end(); ci++) { + cerr << (*ci)->name << endl; + } + cerr << endl; + printUsage(); + retval = 1; } - } else { // command not found - cerr << "Unknown command " << command << "!" << endl << endl; + } else { + cerr << "Unknown command " << commandName << "!" << endl << endl; printUsage(); retval = 1; }