qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH v10 06/13] qapi-visit: Unify struct and union visit


From: Eric Blake
Subject: [Qemu-devel] [PATCH v10 06/13] qapi-visit: Unify struct and union visit
Date: Mon, 15 Feb 2016 17:20:50 -0700

From: Markus Armbruster <address@hidden>

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 slightly changed due to an earlier placement of the
'out_obj' label for structs, but with no semantic impact:

|     if (err) {
|         goto out;
|     }
|     if (!*obj) {
|         goto out_obj;
|     }
|     visit_type_ACPIOSTInfo_fields(v, obj, &err);
|+out_obj:
|     error_propagate(errp, err);
|     err = NULL;
|-out_obj:
|     visit_end_struct(v, &err);
| out:

Signed-off-by: Markus Armbruster <address@hidden>
Message-Id: <address@hidden>
[rebase to earlier changes]
Signed-off-by: Eric Blake <address@hidden>

---
v10: new patch, replacing 31/37
---
 scripts/qapi-visit.py | 96 ++++++++++++++++++---------------------------------
 1 file changed, 34 insertions(+), 62 deletions(-)

diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 0530f2b..786fe57 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -111,40 +111,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);
-    error_propagate(errp, err);
-    err = NULL;
-out_obj:
-    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
@@ -240,14 +206,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)
@@ -264,43 +235,47 @@ 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();
     }
+''')
+
+    ret += mcgen('''
 out_obj:
     error_propagate(errp, err);
     err = NULL;
@@ -362,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.5.0




reply via email to

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