monitor: New format for handlers argument types

Current handlers argument types, as defined in qemu-monitor.hx file,
are a sequence of chars where each one represents one argument type
of the command handler. The number of chars is also used to know how
many arguments a given handler accepts.

This commit defines a new format, which makes mandatory the use of
a name for each argument.

For example, do_eject() command handler is currently defined as:

{ "eject", "-fB", do_eject, ... }

With the new format it becomes:

{ "eject", "force:-f,filename:B", do_eject, ... }

This way the Monitor will be capable of setting up a dictionary, using
each argument's name as the key and the argument itself as the value.

This commit also adds two new functions: key_get_info() and
next_arg_type(), both are used to parse the new format.

Currently key_get_info() consumes the 'key' part of the new format and
discards it, this way the current parsing code is not affected by this
change.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
Luiz Capitulino 2009-08-28 15:27:09 -03:00 committed by Anthony Liguori
parent 3818318682
commit 4d76d2ba9d
2 changed files with 98 additions and 59 deletions

View file

@ -2508,6 +2508,33 @@ static const char *get_command_name(const char *cmdline,
return p;
}
/**
* Read key of 'type' into 'key' and return the current
* 'type' pointer.
*/
static char *key_get_info(const char *type, char **key)
{
size_t len;
char *p, *str;
if (*type == ',')
type++;
p = strchr(type, ':');
if (!p) {
*key = NULL;
return NULL;
}
len = p - type;
str = qemu_malloc(len + 1);
memcpy(str, type, len);
str[len] = '\0';
*key = str;
return ++p;
}
static int default_fmt_format = 'x';
static int default_fmt_size = 4;
@ -2520,6 +2547,7 @@ static void monitor_handle_command(Monitor *mon, const char *cmdline)
const mon_cmd_t *cmd;
char cmdname[256];
char buf[1024];
char *key;
void *str_allocated[MAX_ARGS];
void *args[MAX_ARGS];
void (*handler_0)(Monitor *mon);
@ -2571,9 +2599,10 @@ static void monitor_handle_command(Monitor *mon, const char *cmdline)
typestr = cmd->args_type;
nb_args = 0;
for(;;) {
c = *typestr;
if (c == '\0')
typestr = key_get_info(typestr, &key);
if (!typestr)
break;
c = *typestr;
typestr++;
switch(c) {
case 'F':
@ -2787,6 +2816,8 @@ static void monitor_handle_command(Monitor *mon, const char *cmdline)
monitor_printf(mon, "%s: unknown type '%c'\n", cmdname, c);
goto fail;
}
qemu_free(key);
key = NULL;
}
/* check that all arguments were parsed */
while (qemu_isspace(*p))
@ -2854,6 +2885,7 @@ static void monitor_handle_command(Monitor *mon, const char *cmdline)
qemu_errors_to_previous();
fail:
qemu_free(key);
for(i = 0; i < MAX_ARGS; i++)
qemu_free(str_allocated[i]);
}
@ -2972,6 +3004,12 @@ static void parse_cmdline(const char *cmdline,
*pnb_args = nb_args;
}
static const char *next_arg_type(const char *typestr)
{
const char *p = strchr(typestr, ':');
return (p != NULL ? ++p : typestr);
}
static void monitor_find_completion(const char *cmdline)
{
const char *cmdname;
@ -3014,12 +3052,12 @@ static void monitor_find_completion(const char *cmdline)
}
return;
found:
ptype = cmd->args_type;
ptype = next_arg_type(cmd->args_type);
for(i = 0; i < nb_args - 2; i++) {
if (*ptype != '\0') {
ptype++;
ptype = next_arg_type(ptype);
while (*ptype == '?')
ptype++;
ptype = next_arg_type(ptype);
}
}
str = args[nb_args - 1];