Revision 361127df monitor.c
b/monitor.c | ||
---|---|---|
67 | 67 |
* 'F' filename |
68 | 68 |
* 'B' block device name |
69 | 69 |
* 's' string (accept optional quote) |
70 |
* 'O' option string of the form NAME=VALUE,... |
|
71 |
* parsed according to QemuOptsList given by its name |
|
72 |
* Example: 'device:O' uses qemu_device_opts. |
|
73 |
* Restriction: only lists with empty desc are supported |
|
74 |
* TODO lift the restriction |
|
70 | 75 |
* 'i' 32 bit integer |
71 | 76 |
* 'l' target long (32 or 64 bit) |
72 | 77 |
* 'M' just like 'l', except in user mode the value is |
... | ... | |
3645 | 3650 |
qdict_put(qdict, key, qstring_from_str(buf)); |
3646 | 3651 |
} |
3647 | 3652 |
break; |
3653 |
case 'O': |
|
3654 |
{ |
|
3655 |
QemuOptsList *opts_list; |
|
3656 |
QemuOpts *opts; |
|
3657 |
|
|
3658 |
opts_list = qemu_find_opts(key); |
|
3659 |
if (!opts_list || opts_list->desc->name) { |
|
3660 |
goto bad_type; |
|
3661 |
} |
|
3662 |
while (qemu_isspace(*p)) { |
|
3663 |
p++; |
|
3664 |
} |
|
3665 |
if (!*p) |
|
3666 |
break; |
|
3667 |
if (get_str(buf, sizeof(buf), &p) < 0) { |
|
3668 |
goto fail; |
|
3669 |
} |
|
3670 |
opts = qemu_opts_parse(opts_list, buf, 1); |
|
3671 |
if (!opts) { |
|
3672 |
goto fail; |
|
3673 |
} |
|
3674 |
qemu_opts_to_qdict(opts, qdict); |
|
3675 |
qemu_opts_del(opts); |
|
3676 |
} |
|
3677 |
break; |
|
3648 | 3678 |
case '/': |
3649 | 3679 |
{ |
3650 | 3680 |
int count, format, size; |
... | ... | |
4299 | 4329 |
qint_from_int(qbool_get_int(qobject_to_qbool(value)))); |
4300 | 4330 |
} |
4301 | 4331 |
break; |
4332 |
case 'O': |
|
4302 | 4333 |
default: |
4303 | 4334 |
/* impossible */ |
4304 | 4335 |
abort(); |
... | ... | |
4313 | 4344 |
cmd_args->type = cmd_args->flag = cmd_args->optional = 0; |
4314 | 4345 |
} |
4315 | 4346 |
|
4347 |
static int check_opts(QemuOptsList *opts_list, QDict *args) |
|
4348 |
{ |
|
4349 |
assert(!opts_list->desc->name); |
|
4350 |
return 0; |
|
4351 |
} |
|
4352 |
|
|
4316 | 4353 |
/* |
4317 | 4354 |
* This is not trivial, we have to parse Monitor command's argument |
4318 | 4355 |
* type syntax to be able to check the arguments provided by clients. |
... | ... | |
4325 | 4362 |
int err; |
4326 | 4363 |
const char *p; |
4327 | 4364 |
CmdArgs cmd_args; |
4365 |
QemuOptsList *opts_list; |
|
4328 | 4366 |
|
4329 | 4367 |
if (cmd->args_type == NULL) { |
4330 | 4368 |
return (qdict_size(args) == 0 ? 0 : -1); |
... | ... | |
4332 | 4370 |
|
4333 | 4371 |
err = 0; |
4334 | 4372 |
cmd_args_init(&cmd_args); |
4373 |
opts_list = NULL; |
|
4335 | 4374 |
|
4336 | 4375 |
for (p = cmd->args_type;; p++) { |
4337 | 4376 |
if (*p == ':') { |
... | ... | |
4340 | 4379 |
if (cmd_args.type == '-') { |
4341 | 4380 |
cmd_args.flag = *p++; |
4342 | 4381 |
cmd_args.optional = 1; |
4382 |
} else if (cmd_args.type == 'O') { |
|
4383 |
opts_list = qemu_find_opts(qstring_get_str(cmd_args.name)); |
|
4384 |
assert(opts_list); |
|
4343 | 4385 |
} else if (*p == '?') { |
4344 | 4386 |
cmd_args.optional = 1; |
4345 | 4387 |
p++; |
4346 | 4388 |
} |
4347 | 4389 |
|
4348 | 4390 |
assert(*p == ',' || *p == '\0'); |
4349 |
err = check_arg(&cmd_args, args); |
|
4350 |
|
|
4351 |
QDECREF(cmd_args.name); |
|
4352 |
cmd_args_init(&cmd_args); |
|
4391 |
if (opts_list) { |
|
4392 |
err = check_opts(opts_list, args); |
|
4393 |
opts_list = NULL; |
|
4394 |
} else { |
|
4395 |
err = check_arg(&cmd_args, args); |
|
4396 |
QDECREF(cmd_args.name); |
|
4397 |
cmd_args_init(&cmd_args); |
|
4398 |
} |
|
4353 | 4399 |
|
4354 | 4400 |
if (err < 0) { |
4355 | 4401 |
break; |
Also available in: Unified diff