mirror of https://github.com/xemu-project/xemu.git
monitor: New argument type 'O'
In the human monitor, it declares a single optional argument to be parsed according to the QemuOptsList given by its name. In QMP, it declares an optional argument for each member of the QemuOptsList. Restriction: only lists with empty desc are supported for now. Good enough for the job at hand. We'll lift the restriction when we need that.
This commit is contained in:
parent
304329eea0
commit
361127dfb4
54
monitor.c
54
monitor.c
|
@ -67,6 +67,11 @@
|
||||||
* 'F' filename
|
* 'F' filename
|
||||||
* 'B' block device name
|
* 'B' block device name
|
||||||
* 's' string (accept optional quote)
|
* 's' string (accept optional quote)
|
||||||
|
* 'O' option string of the form NAME=VALUE,...
|
||||||
|
* parsed according to QemuOptsList given by its name
|
||||||
|
* Example: 'device:O' uses qemu_device_opts.
|
||||||
|
* Restriction: only lists with empty desc are supported
|
||||||
|
* TODO lift the restriction
|
||||||
* 'i' 32 bit integer
|
* 'i' 32 bit integer
|
||||||
* 'l' target long (32 or 64 bit)
|
* 'l' target long (32 or 64 bit)
|
||||||
* 'M' just like 'l', except in user mode the value is
|
* 'M' just like 'l', except in user mode the value is
|
||||||
|
@ -3645,6 +3650,31 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon,
|
||||||
qdict_put(qdict, key, qstring_from_str(buf));
|
qdict_put(qdict, key, qstring_from_str(buf));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'O':
|
||||||
|
{
|
||||||
|
QemuOptsList *opts_list;
|
||||||
|
QemuOpts *opts;
|
||||||
|
|
||||||
|
opts_list = qemu_find_opts(key);
|
||||||
|
if (!opts_list || opts_list->desc->name) {
|
||||||
|
goto bad_type;
|
||||||
|
}
|
||||||
|
while (qemu_isspace(*p)) {
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
if (!*p)
|
||||||
|
break;
|
||||||
|
if (get_str(buf, sizeof(buf), &p) < 0) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
opts = qemu_opts_parse(opts_list, buf, 1);
|
||||||
|
if (!opts) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
qemu_opts_to_qdict(opts, qdict);
|
||||||
|
qemu_opts_del(opts);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case '/':
|
case '/':
|
||||||
{
|
{
|
||||||
int count, format, size;
|
int count, format, size;
|
||||||
|
@ -4299,6 +4329,7 @@ static int check_arg(const CmdArgs *cmd_args, QDict *args)
|
||||||
qint_from_int(qbool_get_int(qobject_to_qbool(value))));
|
qint_from_int(qbool_get_int(qobject_to_qbool(value))));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'O':
|
||||||
default:
|
default:
|
||||||
/* impossible */
|
/* impossible */
|
||||||
abort();
|
abort();
|
||||||
|
@ -4313,6 +4344,12 @@ static void cmd_args_init(CmdArgs *cmd_args)
|
||||||
cmd_args->type = cmd_args->flag = cmd_args->optional = 0;
|
cmd_args->type = cmd_args->flag = cmd_args->optional = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int check_opts(QemuOptsList *opts_list, QDict *args)
|
||||||
|
{
|
||||||
|
assert(!opts_list->desc->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is not trivial, we have to parse Monitor command's argument
|
* This is not trivial, we have to parse Monitor command's argument
|
||||||
* type syntax to be able to check the arguments provided by clients.
|
* type syntax to be able to check the arguments provided by clients.
|
||||||
|
@ -4325,6 +4362,7 @@ static int monitor_check_qmp_args(const mon_cmd_t *cmd, QDict *args)
|
||||||
int err;
|
int err;
|
||||||
const char *p;
|
const char *p;
|
||||||
CmdArgs cmd_args;
|
CmdArgs cmd_args;
|
||||||
|
QemuOptsList *opts_list;
|
||||||
|
|
||||||
if (cmd->args_type == NULL) {
|
if (cmd->args_type == NULL) {
|
||||||
return (qdict_size(args) == 0 ? 0 : -1);
|
return (qdict_size(args) == 0 ? 0 : -1);
|
||||||
|
@ -4332,6 +4370,7 @@ static int monitor_check_qmp_args(const mon_cmd_t *cmd, QDict *args)
|
||||||
|
|
||||||
err = 0;
|
err = 0;
|
||||||
cmd_args_init(&cmd_args);
|
cmd_args_init(&cmd_args);
|
||||||
|
opts_list = NULL;
|
||||||
|
|
||||||
for (p = cmd->args_type;; p++) {
|
for (p = cmd->args_type;; p++) {
|
||||||
if (*p == ':') {
|
if (*p == ':') {
|
||||||
|
@ -4340,16 +4379,23 @@ static int monitor_check_qmp_args(const mon_cmd_t *cmd, QDict *args)
|
||||||
if (cmd_args.type == '-') {
|
if (cmd_args.type == '-') {
|
||||||
cmd_args.flag = *p++;
|
cmd_args.flag = *p++;
|
||||||
cmd_args.optional = 1;
|
cmd_args.optional = 1;
|
||||||
|
} else if (cmd_args.type == 'O') {
|
||||||
|
opts_list = qemu_find_opts(qstring_get_str(cmd_args.name));
|
||||||
|
assert(opts_list);
|
||||||
} else if (*p == '?') {
|
} else if (*p == '?') {
|
||||||
cmd_args.optional = 1;
|
cmd_args.optional = 1;
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(*p == ',' || *p == '\0');
|
assert(*p == ',' || *p == '\0');
|
||||||
err = check_arg(&cmd_args, args);
|
if (opts_list) {
|
||||||
|
err = check_opts(opts_list, args);
|
||||||
QDECREF(cmd_args.name);
|
opts_list = NULL;
|
||||||
cmd_args_init(&cmd_args);
|
} else {
|
||||||
|
err = check_arg(&cmd_args, args);
|
||||||
|
QDECREF(cmd_args.name);
|
||||||
|
cmd_args_init(&cmd_args);
|
||||||
|
}
|
||||||
|
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue