diff --git a/qemu/scripts/qapi-event.py b/qemu/scripts/qapi-event.py index aa516ef1..1d154694 100644 --- a/qemu/scripts/qapi-event.py +++ b/qemu/scripts/qapi-event.py @@ -70,36 +70,7 @@ def gen_event_send(name, arg_type): ''', name=name) ret += gen_err_check() - - 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); -''', - cast=cast, - c_name=c_name(memb.name), - c_type=memb.type.c_name(), - name=memb.name) - ret += gen_err_check() - - if memb.optional: - pop_indent() - ret += mcgen(''' - } -''') - + ret += gen_visit_fields(arg_type.members, need_cast=True) ret += mcgen(''' visit_end_struct(v, &err); if (err) { diff --git a/qemu/scripts/qapi-visit.py b/qemu/scripts/qapi-visit.py index fe35d8f9..e709791f 100644 --- a/qemu/scripts/qapi-visit.py +++ b/qemu/scripts/qapi-visit.py @@ -83,27 +83,7 @@ static void visit_type_%(c_name)s_fields(Visitor *v, %(c_name)s **obj, Error **e c_type=base.c_name(), c_name=c_name('base')) ret += gen_err_check() - 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 += gen_err_check() + ret += gen_visit_fields(members, prefix='(*obj)->') if re.search('^ *goto out;', ret, re.MULTILINE): ret += mcgen(''' diff --git a/qemu/scripts/qapi.py b/qemu/scripts/qapi.py index 96287056..51c54549 100644 --- a/qemu/scripts/qapi.py +++ b/qemu/scripts/qapi.py @@ -1543,6 +1543,48 @@ def gen_err_check(err='err', label='out'): err=err, label=label) +def gen_visit_fields(members, prefix='', need_cast=False, errarg='err'): + 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(err=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(err=errarg) + + if memb.optional: + pop_indent() + ret += mcgen(''' + } +''') + return ret + # # Common command line parsing #