Command abbreviation.

This commit is contained in:
Florian Pose 2008-07-22 11:38:21 +00:00
parent e7ee4afed3
commit c57ffba9c8
3 changed files with 69 additions and 33 deletions

View File

@ -47,7 +47,7 @@ void command_alias(void)
unsigned int numSlaves, i;
if (commandArgs.size() != 1) {
err << "'" << command << "' takes exactly one argument!";
err << "'" << commandName << "' takes exactly one argument!";
throw InvalidUsageException(err);
}

View File

@ -21,7 +21,7 @@ enum Verbosity {
Verbose
};
extern string command;
extern string commandName;
extern int slavePosition;
extern int domainIndex;
extern vector<string> commandArgs;

View File

@ -20,7 +20,7 @@ string binaryBaseName;
unsigned int masterIndex = 0;
int slavePosition = -1;
int domainIndex = -1;
string command;
string commandName;
vector<string> commandArgs;
Verbosity verbosity = Normal;
string dataTypeStr;
@ -33,6 +33,7 @@ MasterDevice masterDev;
/*****************************************************************************/
struct Command {
const char *name;
void (*func)(void);
const char *helpString;
@ -40,27 +41,20 @@ struct Command {
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 @@ void printUsage()
<< " 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 <master> Index of the master to use. Default: 0"
<< endl
@ -241,7 +236,7 @@ void getOptions(int argc, char **argv)
exit(!helpRequested);
}
command = argv[optind];
commandName = argv[optind];
while (++optind < argc)
commandArgs.push_back(string(argv[optind]));
}
@ -271,7 +266,41 @@ int Command::execute() const
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<const Command *> getMatchingCommands(const string &cmdStr)
{
const Command *cmd, *endCmd =
commands + sizeof(commands) / sizeof(Command);
list<const Command *> 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 @@ void Command::displayHelp() const
int main(int argc, char **argv)
{
int retval = 0;
const CommandAlias *alias;
const CommandAlias *endAlias =
commandAliases + sizeof(commandAliases) / sizeof(CommandAlias);
list<const Command *> commands;
list<const Command *>::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;
}
commands = getMatchingCommands(commandName);
if (alias < endAlias) { // command alias found
if (!helpRequested) {
masterDev.setIndex(masterIndex);
retval = alias->command->execute();
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;
}