qapi: Drop support for inline nested types
authorEric Blake <eblake@redhat.com>
Mon, 4 May 2015 15:05:33 +0000 (09:05 -0600)
committerMarkus Armbruster <armbru@redhat.com>
Tue, 5 May 2015 16:39:02 +0000 (18:39 +0200)
A future patch will be using a 'name':{dictionary} entry in the
QAPI schema to specify a default value for an optional argument
(see previous commit messages for more details why); but existing
use of inline nested structs conflicts with that goal. Now that
all commands have been changed to avoid inline nested structs,
nuke support for them, and turn it into a hard error. Update the
testsuite to reflect tighter parsing rules.

Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
14 files changed:
scripts/qapi-commands.py
scripts/qapi-event.py
scripts/qapi-types.py
scripts/qapi-visit.py
scripts/qapi.py
tests/qapi-schema/event-nest-struct.err
tests/qapi-schema/nested-struct-data.err
tests/qapi-schema/nested-struct-data.exit
tests/qapi-schema/nested-struct-data.json
tests/qapi-schema/nested-struct-data.out
tests/qapi-schema/nested-struct-returns.err
tests/qapi-schema/nested-struct-returns.exit
tests/qapi-schema/nested-struct-returns.json
tests/qapi-schema/nested-struct-returns.out

index cb786825ee91d6aa23a174252a56e5b94ee165e6..93e43f0e48e4e9f125cb46e4bb26f1cdab94556e 100644 (file)
@@ -28,7 +28,7 @@ def type_visitor(name):
 
 def generate_command_decl(name, args, ret_type):
     arglist=""
-    for argname, argtype, optional, structured in parse_args(args):
+    for argname, argtype, optional in parse_args(args):
         argtype = c_type(argtype, is_param=True)
         if optional:
             arglist += "bool has_%s, " % c_var(argname)
@@ -53,7 +53,7 @@ def gen_sync_call(name, args, ret_type, indent=0):
     retval=""
     if ret_type:
         retval = "retval = "
-    for argname, argtype, optional, structured in parse_args(args):
+    for argname, argtype, optional in parse_args(args):
         if optional:
             arglist += "has_%s, " % c_var(argname)
         arglist += "%s, " % (c_var(argname))
@@ -96,7 +96,7 @@ Visitor *v;
 def gen_visitor_input_vars_decl(args):
     ret = ""
     push_indent()
-    for argname, argtype, optional, structured in parse_args(args):
+    for argname, argtype, optional in parse_args(args):
         if optional:
             ret += mcgen('''
 bool has_%(argname)s = false;
@@ -139,7 +139,7 @@ v = qapi_dealloc_get_visitor(md);
 v = qmp_input_get_visitor(mi);
 ''')
 
-    for argname, argtype, optional, structured in parse_args(args):
+    for argname, argtype, optional in parse_args(args):
         if optional:
             ret += mcgen('''
 visit_optional(v, &has_%(c_name)s, "%(name)s", %(errp)s);
index 601e3076abafe679d4acf13414ba2bd6d9aa1065..47dc041805d8dceddb335aad8b82f0ffb3c04766 100644 (file)
@@ -21,7 +21,7 @@ def _generate_event_api_name(event_name, params):
     l = len(api_name)
 
     if params:
-        for argname, argentry, optional, structured in parse_args(params):
+        for argname, argentry, optional in parse_args(params):
             if optional:
                 api_name += "bool has_%s,\n" % c_var(argname)
                 api_name += "".ljust(l)
@@ -93,7 +93,7 @@ def generate_event_implement(api_name, event_name, params):
 """,
                 event_name = event_name)
 
-        for argname, argentry, optional, structured in parse_args(params):
+        for argname, argentry, optional in parse_args(params):
             if optional:
                 ret += mcgen("""
     if (has_%(var)s) {
index a429d9ec055f3c71d4693b9d0d72a68fb116afbf..2bf814507691b4c6f308da5c51f603e9efb8560d 100644 (file)
@@ -63,18 +63,13 @@ typedef struct %(name)sList
 def generate_struct_fields(members):
     ret = ''
 
-    for argname, argentry, optional, structured in parse_args(members):
+    for argname, argentry, optional in parse_args(members):
         if optional:
             ret += mcgen('''
     bool has_%(c_name)s;
 ''',
                          c_name=c_var(argname))
-        if structured:
-            push_indent()
-            ret += generate_struct({ "field": argname, "data": argentry})
-            pop_indent()
-        else:
-            ret += mcgen('''
+        ret += mcgen('''
     %(c_type)s %(c_name)s;
 ''',
                      c_type=c_type(argentry), c_name=c_var(argname))
index c739a95a87efc5b37af0077d713eb6e086598ee2..61561625007ac3f4e11d7f7f996a5f75fd10332b 100644 (file)
@@ -51,27 +51,6 @@ def generate_visit_struct_fields(name, field_prefix, fn_prefix, members, base =
     else:
         full_name = "%s_%s" % (name, fn_prefix)
 
-    for argname, argentry, optional, structured in parse_args(members):
-        if structured:
-            if not fn_prefix:
-                nested_fn_prefix = argname
-            else:
-                nested_fn_prefix = "%s_%s" % (fn_prefix, argname)
-
-            nested_field_prefix = "%s%s." % (field_prefix, argname)
-            ret += generate_visit_struct_fields(name, nested_field_prefix,
-                                                nested_fn_prefix, argentry)
-            ret += mcgen('''
-
-static void visit_type_%(full_name)s_field_%(c_name)s(Visitor *m, %(name)s **obj, Error **errp)
-{
-''',
-                         name=name, full_name=full_name, c_name=c_var(argname))
-            ret += generate_visit_struct_body(full_name, argname, argentry)
-            ret += mcgen('''
-}
-''')
-
     if base:
         ret += generate_visit_implicit_struct(base)
 
@@ -94,7 +73,7 @@ if (err) {
                      c_prefix=c_var(field_prefix),
                      type=type_name(base), c_name=c_var('base'))
 
-    for argname, argentry, optional, structured in parse_args(members):
+    for argname, argentry, optional in parse_args(members):
         if optional:
             ret += mcgen('''
 visit_optional(m, &(*obj)->%(c_prefix)shas_%(c_name)s, "%(name)s", &err);
@@ -104,18 +83,12 @@ if (!err && (*obj)->%(prefix)shas_%(c_name)s) {
                          c_name=c_var(argname), name=argname)
             push_indent()
 
-        if structured:
-            ret += mcgen('''
-visit_type_%(full_name)s_field_%(c_name)s(m, obj, &err);
-''',
-                         full_name=full_name, c_name=c_var(argname))
-        else:
-            ret += mcgen('''
+        ret += mcgen('''
 visit_type_%(type)s(m, &(*obj)->%(c_prefix)s%(c_name)s, "%(name)s", &err);
 ''',
-                         c_prefix=c_var(field_prefix), prefix=field_prefix,
-                         type=type_name(argentry), c_name=c_var(argname),
-                         name=argname)
+                     c_prefix=c_var(field_prefix), prefix=field_prefix,
+                     type=type_name(argentry), c_name=c_var(argname),
+                     name=argname)
 
         if optional:
             pop_indent()
index 333f59ab5b23440ac8d2249cd6bcd71bea7daf06..44898b082af214399cb189788e82b2ba7064697b 100644 (file)
@@ -373,10 +373,12 @@ def check_type(expr_info, source, value, allow_array = False,
     for (key, arg) in value.items():
         check_name(expr_info, "Member of %s" % source, key,
                    allow_optional=allow_optional)
+        # Todo: allow dictionaries to represent default values of
+        # an optional argument.
         check_type(expr_info, "Member '%s' of %s" % (key, source), arg,
-                   allow_array=True, allow_dict=True, allow_optional=True,
+                   allow_array=True, allow_star=allow_star,
                    allow_metas=['built-in', 'union', 'alternate', 'struct',
-                                'enum'], allow_star=allow_star)
+                                'enum'])
 
 def check_command(expr, expr_info):
     name = expr['command']
@@ -404,13 +406,6 @@ def check_event(expr, expr_info):
     check_type(expr_info, "'data' for event '%s'" % name,
                expr.get('data'), allow_dict=True, allow_optional=True,
                allow_metas=['union', 'struct'])
-    if params:
-        for argname, argentry, optional, structured in parse_args(params):
-            if structured:
-                raise QAPIExprError(expr_info,
-                                    "Nested structure define in event is not "
-                                    "supported, event '%s', argname '%s'"
-                                    % (expr['event'], argname))
 
 def check_union(expr, expr_info):
     name = expr['union']
@@ -671,13 +666,12 @@ def parse_args(typeinfo):
         argname = member
         argentry = typeinfo[member]
         optional = False
-        structured = False
         if member.startswith('*'):
             argname = member[1:]
             optional = True
-        if isinstance(argentry, OrderedDict):
-            structured = True
-        yield (argname, argentry, optional, structured)
+        # Todo: allow argentry to be OrderedDict, for providing the
+        # value of an optional argument.
+        yield (argname, argentry, optional)
 
 def de_camel_case(name):
     new_name = ''
index 91bde1c9678e3b7468da089c9a5e88fc56ad6698..5a42701b8f2f4164909ced660e891147a1426c28 100644 (file)
@@ -1 +1 @@
-tests/qapi-schema/event-nest-struct.json:1: Nested structure define in event is not supported, event 'EVENT_A', argname 'a'
+tests/qapi-schema/event-nest-struct.json:1: Member 'a' of 'data' for event 'EVENT_A' should be a type name
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..da767bade2317b4f41924ffe13ceb2a42ead6c2b 100644 (file)
@@ -0,0 +1 @@
+tests/qapi-schema/nested-struct-data.json:2: Member 'a' of 'data' for command 'foo' should be a type name
index 573541ac9702dd3969c9bc859d2b91ec1f7e6e56..d00491fd7e5bb6fa28c517a0bb32b8b506539d4d 100644 (file)
@@ -1 +1 @@
-0
+1
index 0247c8c82c9c5a1b2bd4b2d1f082101f7c6fa5c0..3d52d2b39818b998d27b98f3a793d10aeaa31806 100644 (file)
@@ -1,4 +1,4 @@
-# FIXME: inline subtypes collide with our desired future use of defaults
+# inline subtypes collide with our desired future use of defaults
 { 'command': 'foo',
   'data': { 'a' : { 'string' : 'str', 'integer': 'int' }, 'b' : 'str' },
   'returns': {} }
index 999cbb8eeffa96f471a39832ea90b7563c204ede..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -1,3 +0,0 @@
-[OrderedDict([('command', 'foo'), ('data', OrderedDict([('a', OrderedDict([('string', 'str'), ('integer', 'int')])), ('b', 'str')])), ('returns', OrderedDict())])]
-[]
-[]
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..5238d075b74c743cdb3667e7ebaa3be4f541f27c 100644 (file)
@@ -0,0 +1 @@
+tests/qapi-schema/nested-struct-returns.json:2: Member 'a' of 'returns' for command 'foo' should be a type name
index 573541ac9702dd3969c9bc859d2b91ec1f7e6e56..d00491fd7e5bb6fa28c517a0bb32b8b506539d4d 100644 (file)
@@ -1 +1 @@
-0
+1
index 5a46840b712314150e9d596ee09b3b2209a211dc..d2cd047f0dd8459dd0d8be064e2e9cd8d54cab9d 100644 (file)
@@ -1,3 +1,3 @@
-# FIXME: inline subtypes collide with our desired future use of defaults
+# inline subtypes collide with our desired future use of defaults
 { 'command': 'foo',
   'returns': { 'a' : { 'string' : 'str', 'integer': 'int' }, 'b' : 'str' } }
index c53d23b3a8d5e8a7e213067c80c524547ceabec8..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -1,3 +0,0 @@
-[OrderedDict([('command', 'foo'), ('returns', OrderedDict([('a', OrderedDict([('string', 'str'), ('integer', 'int')])), ('b', 'str')]))])]
-[]
-[]
This page took 0.043892 seconds and 4 git commands to generate.