qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 3/3] qapi-visit: Unify struct and union visit


From: Markus Armbruster
Subject: [Qemu-devel] [PATCH 3/3] qapi-visit: Unify struct and union visit
Date: Wed, 27 Jan 2016 14:54:48 +0100

gen_visit_union() is now just like gen_visit_struct() plus additional
code to handle variants.  Make that code conditional on variants, so
gen_visit_union() does exactly the same for structs as
gen_visit_struct().  Rename it to gen_visit_object(), use it for
structs, and drop gen_visit_struct().

Output is identical.

Signed-off-by: Markus Armbruster <address@hidden>
---
 scripts/qapi-visit.py | 95 ++++++++++++++++++---------------------------------
 1 file changed, 33 insertions(+), 62 deletions(-)

diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 8dcc6dc..9e044c2 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -109,40 +109,6 @@ out:
     return ret
 
 
-def gen_visit_struct(name, base, members):
-    ret = gen_visit_struct_fields(name, base, members)
-
-    # FIXME: if *obj is NULL on entry, and visit_start_struct() assigns to
-    # *obj, but then visit_type_FOO_fields() fails, we should clean up *obj
-    # rather than leaving it non-NULL. As currently written, the caller must
-    # call qapi_free_FOO() to avoid a memory leak of the partial FOO.
-    ret += mcgen('''
-
-void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s **obj, 
Error **errp)
-{
-    Error *err = NULL;
-
-    visit_start_struct(v, name, (void **)obj, sizeof(%(c_name)s), &err);
-    if (err) {
-        goto out;
-    }
-    if (!*obj) {
-        goto out_obj;
-    }
-    visit_type_%(c_name)s_fields(v, obj, &err);
-out_obj:
-    error_propagate(errp, err);
-    err = NULL;
-    visit_end_struct(v, &err);
-out:
-    error_propagate(errp, err);
-}
-''',
-                 c_name=c_name(name))
-
-    return ret
-
-
 def gen_visit_list(name, element_type):
     # FIXME: if *obj is NULL on entry, and the first visit_next_list()
     # assigns to *obj, while a later one fails, we should clean up *obj
@@ -238,14 +204,19 @@ out:
     return ret
 
 
-def gen_visit_union(name, base, members, variants):
+def gen_visit_object(name, base, members, variants):
     ret = gen_visit_struct_fields(name, base, members)
 
-    for var in variants.variants:
-        # Ugly special case for simple union TODO get rid of it
-        if not var.simple_union_type():
-            ret += gen_visit_implicit_struct(var.type)
+    if variants:
+        for var in variants.variants:
+            # Ugly special case for simple union TODO get rid of it
+            if not var.simple_union_type():
+                ret += gen_visit_implicit_struct(var.type)
 
+    # FIXME: if *obj is NULL on entry, and visit_start_struct() assigns to
+    # *obj, but then visit_type_FOO_fields() fails, we should clean up *obj
+    # rather than leaving it non-NULL. As currently written, the caller must
+    # call qapi_free_FOO() to avoid a memory leak of the partial FOO.
     ret += mcgen('''
 
 void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s **obj, 
Error **errp)
@@ -262,46 +233,49 @@ void visit_type_%(c_name)s(Visitor *v, const char *name, 
%(c_name)s **obj, Error
     visit_type_%(c_name)s_fields(v, obj, &err);
 ''',
                  c_name=c_name(name))
-    ret += gen_err_check(label='out_obj')
-    ret += mcgen('''
+    if variants:
+        ret += gen_err_check(label='out_obj')
+        ret += mcgen('''
     if (!visit_start_union(v, !!(*obj)->u.data, &err) || err) {
         goto out_obj;
     }
     switch ((*obj)->%(c_name)s) {
 ''',
-                 c_name=c_name(variants.tag_member.name))
+                     c_name=c_name(variants.tag_member.name))
 
-    for var in variants.variants:
-        # TODO ugly special case for simple union
-        simple_union_type = var.simple_union_type()
-        ret += mcgen('''
+        for var in variants.variants:
+            # TODO ugly special case for simple union
+            simple_union_type = var.simple_union_type()
+            ret += mcgen('''
     case %(case)s:
 ''',
-                     case=c_enum_const(variants.tag_member.type.name,
-                                       var.name))
-        if simple_union_type:
-            ret += mcgen('''
+                         case=c_enum_const(variants.tag_member.type.name,
+                                           var.name))
+            if simple_union_type:
+                ret += mcgen('''
         visit_type_%(c_type)s(v, "data", &(*obj)->u.%(c_name)s, &err);
 ''',
-                         c_type=simple_union_type.c_name(),
-                         c_name=c_name(var.name))
-        else:
-            ret += mcgen('''
+                             c_type=simple_union_type.c_name(),
+                             c_name=c_name(var.name))
+            else:
+                ret += mcgen('''
         visit_type_implicit_%(c_type)s(v, &(*obj)->u.%(c_name)s, &err);
 ''',
-                         c_type=var.type.c_name(),
-                         c_name=c_name(var.name))
-        ret += mcgen('''
+                             c_type=var.type.c_name(),
+                             c_name=c_name(var.name))
+            ret += mcgen('''
         break;
 ''')
 
-    ret += mcgen('''
+        ret += mcgen('''
     default:
         abort();
     }
     error_propagate(errp, err);
     err = NULL;
     visit_end_union(v, !!(*obj)->u.data, &err);
+''')
+    ret += mcgen('''
 out_obj:
     error_propagate(errp, err);
     err = NULL;
@@ -363,10 +337,7 @@ class QAPISchemaGenVisitVisitor(QAPISchemaVisitor):
 
     def visit_object_type(self, name, info, base, members, variants):
         self.decl += gen_visit_decl(name)
-        if variants:
-            self.defn += gen_visit_union(name, base, members, variants)
-        else:
-            self.defn += gen_visit_struct(name, base, members)
+        self.defn += gen_visit_object(name, base, members, variants)
 
     def visit_alternate_type(self, name, info, variants):
         self.decl += gen_visit_decl(name)
-- 
2.4.3




reply via email to

[Prev in Thread] Current Thread [Next in Thread]