diff -r 764e41b09017 tools/libxl/xl.c --- a/tools/libxl/xl.c Thu Jun 17 08:53:12 2010 +0100 +++ b/tools/libxl/xl.c Thu Jun 17 16:51:34 2010 +0100 @@ -37,8 +37,9 @@ int main(int argc, char **argv) { - int opt = 0, i; + int opt = 0; char *cmd = 0; + struct cmd_spec *cspec; while ((opt = getopt(argc, argv, "+v")) >= 0) { switch (opt) { @@ -69,18 +70,14 @@ srand(time(0)); - for (i = 0; i < cmdtable_len; i++) { - if (!strcmp(cmd, cmd_table[i].cmd_name)) - cmd_table[i].cmd_impl(argc, argv); - } - - if (i >= cmdtable_len) { - if (!strcmp(cmd, "help")) { - help(argv[2]); - exit(0); - } else { - fprintf(stderr, "command not implemented\n"); - exit(1); - } + cspec = cmdtable_lookup(cmd); + if (cspec) + return cspec->cmd_impl(argc, argv); + else if (!strcmp(cmd, "help")) { + help(argv[2]); + exit(0); + } else { + fprintf(stderr, "command not implemented\n"); + exit(1); } } diff -r 764e41b09017 tools/libxl/xl.h --- a/tools/libxl/xl.h Thu Jun 17 08:53:12 2010 +0100 +++ b/tools/libxl/xl.h Thu Jun 17 16:51:34 2010 +0100 @@ -80,6 +80,8 @@ extern struct cmd_spec cmd_table[]; extern int cmdtable_len; +/* Look up a command in the table, allowing unambiguous truncation */ +struct cmd_spec *cmdtable_lookup(const char *s); extern struct libxl_ctx ctx; extern xentoollog_logger_stdiostream *logger; diff -r 764e41b09017 tools/libxl/xl_cmdimpl.c --- a/tools/libxl/xl_cmdimpl.c Thu Jun 17 08:53:12 2010 +0100 +++ b/tools/libxl/xl_cmdimpl.c Thu Jun 17 16:51:34 2010 +0100 @@ -1282,6 +1282,7 @@ void help(char *command) { int i; + struct cmd_spec *cmd; if (!command || !strcmp(command, "help")) { printf("Usage xl [args]\n\n"); @@ -1290,18 +1291,17 @@ printf(" %-20s%s\n", cmd_table[i].cmd_name, cmd_table[i].cmd_desc); } else { - for (i = 0; i < cmdtable_len; i++) - if (!strcmp(command, cmd_table[i].cmd_name)) - break; - if (i == cmdtable_len) { - printf("command not implemented\n"); - } else { + cmd = cmdtable_lookup(command); + if (cmd) { printf("Usage: xl %s %s\n\n%s.\n\n", - cmd_table[i].cmd_name, - cmd_table[i].cmd_usage, - cmd_table[i].cmd_desc); - if (cmd_table[i].cmd_option) - printf("Options:\n\n%s\n", cmd_table[i].cmd_option); + cmd->cmd_name, + cmd->cmd_usage, + cmd->cmd_desc); + if (cmd->cmd_option) + printf("Options:\n\n%s\n", cmd->cmd_option); + } + else { + printf("command \"%s\" not implemented\n", command); } } } diff -r 764e41b09017 tools/libxl/xl_cmdtable.c --- a/tools/libxl/xl_cmdtable.c Thu Jun 17 08:53:12 2010 +0100 +++ b/tools/libxl/xl_cmdtable.c Thu Jun 17 16:51:34 2010 +0100 @@ -11,6 +11,8 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. */ + +#include #include "xl.h" @@ -308,3 +310,24 @@ }; int cmdtable_len = sizeof(cmd_table)/sizeof(struct cmd_spec); + +/* Look up a command in the table, allowing unambiguous truncation */ +struct cmd_spec *cmdtable_lookup(const char *s) +{ + struct cmd_spec *cmd = NULL; + size_t len; + int i; + + if (!s) + return NULL; + len = strlen(s); + for (i = 0; i < cmdtable_len; i++) { + if (!strncmp(s, cmd_table[i].cmd_name, len)) { + if (cmd == NULL) + cmd = &cmd_table[i]; + else + return NULL; + } + } + return cmd; +}