[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v5 10/46] qapi: Merge generation of per-member visit
From: |
Eric Blake |
Subject: |
[Qemu-devel] [PATCH v5 10/46] qapi: Merge generation of per-member visits |
Date: |
Mon, 21 Sep 2015 15:57:26 -0600 |
Consolidate the code between visit, command marshalling, and
event generation that iterates over the members of a struct.
It reduces code duplication in the generator, with no change to
generated marshal code, slightly more verbose visit code:
| visit_optional(v, &(*obj)->has_device, "device", &err);
|- if (!err && (*obj)->has_device) {
|- visit_type_str(v, &(*obj)->device, "device", &err);
|- }
| if (err) {
| goto out;
| }
|+ if ((*obj)->has_device) {
|+ visit_type_str(v, &(*obj)->device, "device", &err);
|+ if (err) {
|+ goto out;
|+ }
|+ }
and slightly more verbose event code (recall that the qmp
output visitor has a no-op visit_optional()):
|+ visit_optional(v, &has_offset, "offset", &err);
|+ if (err) {
|+ goto out;
|+ }
| if (has_offset) {
| visit_type_int(v, &offset, "offset", &err);
Signed-off-by: Eric Blake <address@hidden>
---
scripts/qapi-commands.py | 38 +---------------------------------
scripts/qapi-event.py | 35 +++-----------------------------
scripts/qapi-visit.py | 26 +-----------------------
scripts/qapi.py | 53 ++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 58 insertions(+), 94 deletions(-)
diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index 2151120..55287b1 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -25,17 +25,6 @@ def gen_command_decl(name, arg_type, ret_type):
params=gen_params(arg_type, 'Error **errp'))
-def gen_err_check(err):
- if not err:
- return ''
- return mcgen('''
-if (%(err)s) {
- goto out;
-}
-''',
- err=err)
-
-
def gen_call(name, arg_type, ret_type):
ret = ''
@@ -119,7 +108,6 @@ def gen_marshal_input_visit(arg_type, dealloc=False):
push_indent()
if dealloc:
- errparg = 'NULL'
errarg = None
ret += mcgen('''
qmp_input_visitor_cleanup(mi);
@@ -127,36 +115,12 @@ md = qapi_dealloc_visitor_new();
v = qapi_dealloc_get_visitor(md);
''')
else:
- errparg = '&err'
errarg = 'err'
ret += mcgen('''
v = qmp_input_get_visitor(mi);
''')
- for memb in arg_type.members:
- if memb.optional:
- ret += mcgen('''
-visit_optional(v, &has_%(c_name)s, "%(name)s", %(errp)s);
-''',
- c_name=c_name(memb.name), name=memb.name,
- errp=errparg)
- ret += gen_err_check(errarg)
- ret += mcgen('''
-if (has_%(c_name)s) {
-''',
- c_name=c_name(memb.name))
- push_indent()
- ret += mcgen('''
-visit_type_%(c_type)s(v, &%(c_name)s, "%(name)s", %(errp)s);
-''',
- c_name=c_name(memb.name), name=memb.name,
- c_type=memb.type.c_name(), errp=errparg)
- ret += gen_err_check(errarg)
- if memb.optional:
- pop_indent()
- ret += mcgen('''
-}
-''')
+ ret += gen_visit_fields(arg_type.members, '', False, errarg)
if dealloc:
ret += mcgen('''
diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py
index b43bbc2..6c70a06 100644
--- a/scripts/qapi-event.py
+++ b/scripts/qapi-event.py
@@ -74,38 +74,9 @@ def gen_event_send(name, arg_type):
''',
name=name)
-
- for memb in arg_type.members:
- if memb.optional:
- ret += mcgen('''
- if (has_%(c_name)s) {
-''',
- c_name=c_name(memb.name))
- push_indent()
-
- # Ugly: need to cast away the const
- if memb.type.name == "str":
- cast = '(char **)'
- else:
- cast = ''
-
- ret += mcgen('''
- visit_type_%(c_type)s(v, %(cast)s&%(c_name)s, "%(name)s", &err);
- if (err) {
- goto out;
- }
-''',
- cast=cast,
- c_name=c_name(memb.name),
- c_type=memb.type.c_name(),
- name=memb.name)
-
- if memb.optional:
- pop_indent()
- ret += mcgen('''
- }
-''')
-
+ push_indent()
+ ret += gen_visit_fields(arg_type.members, '', True, 'err')
+ pop_indent()
ret += mcgen('''
visit_end_struct(v, &err);
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 9c0328d..1f287ba 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -88,31 +88,7 @@ if (err) {
''',
c_type=base.c_name(), c_name=c_name('base'))
- for memb in members:
- if memb.optional:
- ret += mcgen('''
-visit_optional(v, &(*obj)->has_%(c_name)s, "%(name)s", &err);
-if (!err && (*obj)->has_%(c_name)s) {
-''',
- c_name=c_name(memb.name), name=memb.name)
- push_indent()
-
- ret += mcgen('''
-visit_type_%(c_type)s(v, &(*obj)->%(c_name)s, "%(name)s", &err);
-''',
- c_type=memb.type.c_name(), c_name=c_name(memb.name),
- name=memb.name)
-
- if memb.optional:
- pop_indent()
- ret += mcgen('''
-}
-''')
- ret += mcgen('''
-if (err) {
- goto out;
-}
-''')
+ ret += gen_visit_fields(members, '(*obj)->', False, 'err')
pop_indent()
if re.search('^ *goto out;', ret, re.MULTILINE):
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 6f4e471..7275daa 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -1531,6 +1531,59 @@ def gen_params(arg_type, extra):
ret += sep + extra
return ret
+
+def gen_err_check(err):
+ if not err:
+ return ''
+ return mcgen('''
+if (%(err)s) {
+ goto out;
+}
+''',
+ err=err)
+
+
+def gen_visit_fields(members, prefix, need_cast, errarg):
+ ret = ''
+ if errarg:
+ errparg = '&' + errarg
+ else:
+ errparg = 'NULL'
+ for memb in members:
+ if memb.optional:
+ ret += mcgen('''
+visit_optional(v, &%(prefix)shas_%(c_name)s, "%(name)s", %(errp)s);
+''',
+ prefix=prefix, c_name=c_name(memb.name),
+ name=memb.name, errp=errparg)
+ ret += gen_err_check(errarg)
+ ret += mcgen('''
+if (%(prefix)shas_%(c_name)s) {
+''',
+ prefix=prefix, c_name=c_name(memb.name))
+ push_indent()
+
+ # Ugly: sometimes we need to cast away const
+ if need_cast and memb.type.name == 'str':
+ cast = '(char **)'
+ else:
+ cast = ''
+
+ ret += mcgen('''
+visit_type_%(c_type)s(v, %(cast)s&%(prefix)s%(c_name)s, "%(name)s", %(errp)s);
+''',
+ c_type=memb.type.c_name(), prefix=prefix, cast=cast,
+ c_name=c_name(memb.name), name=memb.name,
+ errp=errparg)
+ ret += gen_err_check(errarg)
+
+ if memb.optional:
+ pop_indent()
+ ret += mcgen('''
+}
+''')
+ return ret
+
#
# Common command line parsing
#
--
2.4.3
[Qemu-devel] [PATCH v5 08/46] qapi: Reuse code for flat union base validation, Eric Blake, 2015/09/21
[Qemu-devel] [PATCH v5 09/46] qapi: Use consistent generated code patterns, Eric Blake, 2015/09/21
[Qemu-devel] [PATCH v5 10/46] qapi: Merge generation of per-member visits,
Eric Blake <=
[Qemu-devel] [PATCH v5 11/46] qapi: Don't use info as witness of implicit object type, Eric Blake, 2015/09/21
[Qemu-devel] [PATCH v5 12/46] qapi: Track location that created an implicit type, Eric Blake, 2015/09/21
[Qemu-devel] [PATCH v5 14/46] qapi: Detect collisions in C member names, Eric Blake, 2015/09/21
[Qemu-devel] [PATCH v5 16/46] qapi: Detect base class loops, Eric Blake, 2015/09/21