Skip to content

Commit

Permalink
monitor: refine monitor_find_completion()
Browse files Browse the repository at this point in the history
In order to support sub command in auto completion, a reentrant function
is needed, so monitor_find_completion() is split into two parts. The
first part does parsing of user input which need to be done only once,
the second part does the auto completion job according to the parsing
result, which contains the necessary code to support sub command and
works as the reentrant function. The global "info_cmds" is still used
in second part, which will be replaced by sub command code later.

Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
  • Loading branch information
Wenchao Xia authored and Luiz Capitulino committed Aug 30, 2013
1 parent 6685549 commit c35b640
Showing 1 changed file with 39 additions and 26 deletions.
65 changes: 39 additions & 26 deletions monitor.c
Expand Up @@ -4230,53 +4230,36 @@ static const char *next_arg_type(const char *typestr)
return (p != NULL ? ++p : typestr);
}

static void monitor_find_completion(Monitor *mon,
const char *cmdline)
static void monitor_find_completion_by_table(Monitor *mon,
const mon_cmd_t *cmd_table,
char **args,
int nb_args)
{
const char *cmdname;
char *args[MAX_ARGS];
int nb_args, i, len;
int i;
const char *ptype, *str;
const mon_cmd_t *cmd;
MonitorBlockComplete mbs;

if (parse_cmdline(cmdline, &nb_args, args) < 0) {
return;
}
#ifdef DEBUG_COMPLETION
for (i = 0; i < nb_args; i++) {
monitor_printf(mon, "arg%d = '%s'\n", i, args[i]);
}
#endif

/* if the line ends with a space, it means we want to complete the
next arg */
len = strlen(cmdline);
if (len > 0 && qemu_isspace(cmdline[len - 1])) {
if (nb_args >= MAX_ARGS) {
goto cleanup;
}
args[nb_args++] = g_strdup("");
}
if (nb_args <= 1) {
/* command completion */
if (nb_args == 0)
cmdname = "";
else
cmdname = args[0];
readline_set_completion_index(mon->rs, strlen(cmdname));
for (cmd = mon->cmd_table; cmd->name != NULL; cmd++) {
for (cmd = cmd_table; cmd->name != NULL; cmd++) {
cmd_completion(mon, cmdname, cmd->name);
}
} else {
/* find the command */
for (cmd = mon->cmd_table; cmd->name != NULL; cmd++) {
for (cmd = cmd_table; cmd->name != NULL; cmd++) {
if (compare_cmd(args[0], cmd->name)) {
break;
}
}
if (!cmd->name) {
goto cleanup;
return;
}

ptype = next_arg_type(cmd->args_type);
Expand Down Expand Up @@ -4321,7 +4304,7 @@ static void monitor_find_completion(Monitor *mon,
}
} else if (!strcmp(cmd->name, "help|?")) {
readline_set_completion_index(mon->rs, strlen(str));
for (cmd = mon->cmd_table; cmd->name != NULL; cmd++) {
for (cmd = cmd_table; cmd->name != NULL; cmd++) {
cmd_completion(mon, str, cmd->name);
}
}
Expand All @@ -4330,6 +4313,36 @@ static void monitor_find_completion(Monitor *mon,
break;
}
}
}

static void monitor_find_completion(Monitor *mon,
const char *cmdline)
{
char *args[MAX_ARGS];
int nb_args, len;

/* 1. parse the cmdline */
if (parse_cmdline(cmdline, &nb_args, args) < 0) {
return;
}
#ifdef DEBUG_COMPLETION
for (i = 0; i < nb_args; i++) {
monitor_printf(mon, "arg%d = '%s'\n", i, args[i]);
}
#endif

/* if the line ends with a space, it means we want to complete the
next arg */
len = strlen(cmdline);
if (len > 0 && qemu_isspace(cmdline[len - 1])) {
if (nb_args >= MAX_ARGS) {
goto cleanup;
}
args[nb_args++] = g_strdup("");
}

/* 2. auto complete according to args */
monitor_find_completion_by_table(mon, mon->cmd_table, args, nb_args);

cleanup:
free_cmdline_args(args, nb_args);
Expand Down

0 comments on commit c35b640

Please sign in to comment.