[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 15/18] qapi: implement support for variable argument
From: |
Luiz Capitulino |
Subject: |
[Qemu-devel] [PATCH 15/18] qapi: implement support for variable argument list |
Date: |
Tue, 17 Apr 2012 16:36:18 -0300 |
The variable argument list allows QAPI functions to receive a
string in the format "name1=value1,name2=value2 ... nameN=valueN".
This is going to be used by QMP commands that accept options in
QemuOpts format, like netdev_add.
The variable argument list is represented by the QAPI type '**'. It's
declared like this in the schema:
{ 'command': 'cmd-foo', 'data': { 'arglist': '**' } }
and the code generator will generate the following signature for cmd-foo:
void cmd_foo(const char *arglist, Error **errp);
The argument list can be accessed in 'arglist'.
Signed-off-by: Luiz Capitulino <address@hidden>
---
scripts/qapi-commands.py | 91 ++++++++++++++++++++++++++++++++++++++++++++++
scripts/qapi.py | 2 +
2 files changed, 93 insertions(+)
diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index 0b4f0a0..1506263 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -122,6 +122,10 @@ bool has_%(argname)s = false;
%(argtype)s %(argname)s;
''',
argname=c_var(argname), argtype=c_type(argtype))
+ if argtype == '**':
+ ret += mcgen('''
+QString *arglist = NULL;
+''')
pop_indent()
return ret.rstrip()
@@ -146,6 +150,8 @@ v = qmp_input_get_visitor(mi);
obj=obj)
for argname, argtype, optional, structured in parse_args(args):
+ if argtype == '**':
+ continue
if optional:
ret += mcgen('''
visit_start_optional(v, &has_%(c_name)s, "%(name)s", errp);
@@ -257,6 +263,86 @@ def gen_marshal_input(name, args, ret_type, middle_mode):
if (error_is_set(errp)) {
goto out;
}
+''')
+
+ # '**' implementation
+ regular_args = []
+ var_list_name = ""
+ for argname, argtype, optional, structured in parse_args(args):
+ if argtype == '**':
+ var_list_name = argname
+ else:
+ regular_args.append(argname)
+
+ if var_list_name:
+ ret += mcgen('''
+ else {
+ const QDictEntry *entry;
+
+ arglist = qstring_new();
+ for (entry = qdict_first(args); entry;
+ entry = qdict_next(qdict, entry)) {
+ const QObject *obj = qdict_entry_value(entry);
+ char buf[32];
+ int n;
+
+''')
+ for argname in regular_args:
+ ret += mcgen('''
+ if (strcmp(qdict_entry_key(entry), "%(argname)s") == 0) {
+ continue;
+ }
+
+''', argname=argname)
+
+ ret += mcgen('''
+ if (qstring_len(arglist) > 0) {
+ qstring_append(arglist, ",");
+ }
+
+ qstring_append(arglist, qdict_entry_key(entry));
+ qstring_append(arglist, "=");
+
+ switch(qobject_type(obj)) {
+ case QTYPE_QSTRING:
+ qstring_append(arglist,
+ qstring_get_str(qobject_to_qstring(obj)));
+ break;
+ case QTYPE_QINT:
+ n = snprintf(buf, sizeof(buf), %(arg1)s,
+ qint_get_int(qobject_to_qint(obj)));
+ assert(n < sizeof(buf));
+ qstring_append(arglist, buf);
+ break;
+ case QTYPE_QFLOAT:
+ n = snprintf(buf, sizeof(buf), %(arg2)s,
+ qfloat_get_double(qobject_to_qfloat(obj)));
+ qstring_append(arglist, buf);
+ break;
+ case QTYPE_QBOOL:
+ pstrcpy(buf, sizeof(buf),
+ qbool_get_int(qobject_to_qbool(obj)) ? "on" : "off");
+ qstring_append(arglist, buf);
+ break;
+ default:
+ QDECREF(arglist);
+ error_set(&local_err, QERR_INVALID_PARAMETER_TYPE,
+ qdict_entry_key(entry),
+ "string, int, float or bool");
+ goto out;
+ }
+ }
+
+ if (qstring_len(arglist) > 0) {
+ has_%(var_list_name)s = true;
+ %(var_list_name)s = qstring_get_str(arglist);
+ }
+ }
+
+''', var_list_name=c_var(var_list_name), arg1='"%" PRId64', arg2='"%.17g"',
+ arg3='"%d"')
+
+ ret += mcgen('''
%(sync_call)s
''',
sync_call=gen_sync_call(name, args, ret_type, indent=4))
@@ -270,6 +356,11 @@ out:
visitor_input_block_cleanup=gen_visitor_input_block(args,
None,
dealloc=True))
+ if var_list_name:
+ ret += mcgen('''
+ QDECREF(arglist);
+''')
+
if middle_mode:
ret += mcgen('''
diff --git a/scripts/qapi.py b/scripts/qapi.py
index e062336..9bd6e95 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -163,6 +163,8 @@ def c_type(name):
return 'bool'
elif name == 'number':
return 'double'
+ elif name == '**':
+ return 'const char *'
elif type(name) == list:
return '%s *' % c_list_type(name[0])
elif is_enum(name):
--
1.7.9.2.384.g4a92a
- [Qemu-devel] [PATCH 08/18] qemu-option: opts_do_parse(): use error_set(), (continued)
- [Qemu-devel] [PATCH 08/18] qemu-option: opts_do_parse(): use error_set(), Luiz Capitulino, 2012/04/17
- [Qemu-devel] [PATCH 09/18] qemu-option: qemu_opts_do_parse(): convert error_set(), Luiz Capitulino, 2012/04/17
- [Qemu-devel] [PATCH 04/18] qemu-option: parse_option_size(): use error_set(), Luiz Capitulino, 2012/04/17
- [Qemu-devel] [PATCH 14/18] qstring: introduce qstring_len(), Luiz Capitulino, 2012/04/17
- [Qemu-devel] [PATCH 03/18] qemu-option: parse_option_bool(): use error_set(), Luiz Capitulino, 2012/04/17
- [Qemu-devel] [PATCH 11/18] qerror: introduce QERR_INVALID_OPTION_GROUP, Luiz Capitulino, 2012/04/17
- [Qemu-devel] [PATCH 12/18] qemu-config: find_list(): use error_set(), Luiz Capitulino, 2012/04/17
- [Qemu-devel] [PATCH 16/18] net: purge the monitor object from all init functions, Luiz Capitulino, 2012/04/17
- [Qemu-devel] [PATCH 17/18] qapi: convert netdev_add, Luiz Capitulino, 2012/04/17
- [Qemu-devel] [PATCH 18/18] qapi: convert netdev_del, Luiz Capitulino, 2012/04/17
- [Qemu-devel] [PATCH 15/18] qapi: implement support for variable argument list,
Luiz Capitulino <=
- Re: [Qemu-devel] [PATCH 15/18] qapi: implement support for variable argument list, Anthony Liguori, 2012/04/18
- Re: [Qemu-devel] [PATCH 15/18] qapi: implement support for variable argument list, Luiz Capitulino, 2012/04/18
- Re: [Qemu-devel] [PATCH 15/18] qapi: implement support for variable argument list, Paolo Bonzini, 2012/04/18
[Qemu-devel] [PATCH 13/18] qemu-config: introduce qemu_find_opts_err(), Luiz Capitulino, 2012/04/17