All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eric Blake <eblake@redhat.com>
To: qemu-devel@nongnu.org
Cc: armbru@redhat.com, Michael Roth <mdroth@linux.vnet.ibm.com>
Subject: [Qemu-devel] [PATCH v9 03/17] qapi: Reserve 'u' and 'has[-_]*' member names
Date: Thu, 15 Oct 2015 22:15:28 -0600	[thread overview]
Message-ID: <1444968943-11254-4-git-send-email-eblake@redhat.com> (raw)
In-Reply-To: <1444968943-11254-1-git-send-email-eblake@redhat.com>

To make collision detection between member names easier, we
might as well reject all attempts to use anything that would
collide with our use of 'has_' as a flag for optional members.
Also, a later patch will introduce a named union 'u' for
holding the branch names of a qapi union in a separate
namespace from non-variant QMP members, at which point it
would collide with a 'u' member.  Fortunately, none of our
qapi files were using these names, so we can reserve them now.

Note that we cannot forbid 'u' everywhere (by adding the
rejection code to check_name()), because the existing QKeyCode
enum already uses it, and because qapi-schema-test.json
intentionally uses it as a branch name (we could feasibly have
a union with one branch per QKeyCode).  Also, forbidding 'has_'
in branch names will eventually disappear, once branch names
cannot collide with other names.  So instead, this code does
separate checks for check_type() (when iterating over a dict,
common to struct, command args, and event data) and for
unions.  We do NOT need to reserve the names for alternates,
because alternates do not have any QMP members alongside its
branch names.

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v9: new patch
---
 docs/qapi-code-gen.txt                         |  5 ++++-
 scripts/qapi.py                                | 12 ++++++++++++
 tests/qapi-schema/args-name-has.err            |  1 +
 tests/qapi-schema/args-name-has.exit           |  2 +-
 tests/qapi-schema/args-name-has.json           |  7 +++----
 tests/qapi-schema/args-name-has.out            |  6 ------
 tests/qapi-schema/flat-union-clash-branch.err  |  1 +
 tests/qapi-schema/flat-union-clash-branch.exit |  2 +-
 tests/qapi-schema/flat-union-clash-branch.json |  7 ++++---
 tests/qapi-schema/flat-union-clash-branch.out  | 11 -----------
 tests/qapi-schema/qapi-schema-test.json        |  9 ++++-----
 tests/qapi-schema/struct-member-u.err          |  1 +
 tests/qapi-schema/struct-member-u.exit         |  2 +-
 tests/qapi-schema/struct-member-u.json         |  8 ++++----
 tests/qapi-schema/struct-member-u.out          |  3 ---
 15 files changed, 37 insertions(+), 40 deletions(-)

diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
index c4264a8..df2d198 100644
--- a/docs/qapi-code-gen.txt
+++ b/docs/qapi-code-gen.txt
@@ -112,7 +112,10 @@ and field names within a type, should be all lower case with words
 separated by a hyphen.  However, some existing older commands and
 complex types use underscore; when extending such expressions,
 consistency is preferred over blindly avoiding underscore.  Event
-names should be ALL_CAPS with words separated by underscore.
+names should be ALL_CAPS with words separated by underscore.  Field
+names cannot be 'u', as this is reserved for generated code for
+unions, nor can they start with 'has-' or 'has_', as this is
+reserved for tracking optional fields.

 Any name (command, event, type, field, or enum value) beginning with
 "x-" is marked experimental, and may be withdrawn or changed
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 09ba44b..1e7e08b 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -488,6 +488,10 @@ 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)
+        if key == 'u' or key.startswith('has-') or key.startswith('has_'):
+            raise QAPIExprError(expr_info,
+                                "Member of %s uses reserved name '%s'"
+                                % (source, key))
         # Todo: allow dictionaries to represent default values of
         # an optional argument.
         check_type(expr_info, "Member '%s' of %s" % (key, source), arg,
@@ -588,6 +592,14 @@ def check_union(expr, expr_info):
     # Check every branch
     for (key, value) in members.items():
         check_name(expr_info, "Member of union '%s'" % name, key)
+        # TODO: As long as branch names can collide with QMP names, we
+        # must prevent branches starting with 'has_'. However, we do not
+        # need to reject 'u', because that is reserved for when we start
+        # sticking branch names in a C union named 'u'.
+        if key.startswith('has-') or key.startswith('has_'):
+            raise QAPIExprError(expr_info,
+                                "Branch of union '%s' uses reserved name '%s'"
+                                % (name, key))

         # Each value must name a known type; furthermore, in flat unions,
         # branches must be a struct with no overlapping member names
diff --git a/tests/qapi-schema/args-name-has.err b/tests/qapi-schema/args-name-has.err
index e69de29..cb57552 100644
--- a/tests/qapi-schema/args-name-has.err
+++ b/tests/qapi-schema/args-name-has.err
@@ -0,0 +1 @@
+tests/qapi-schema/args-name-has.json:5: Member of 'data' for command 'oops' uses reserved name 'has-a'
diff --git a/tests/qapi-schema/args-name-has.exit b/tests/qapi-schema/args-name-has.exit
index 573541a..d00491f 100644
--- a/tests/qapi-schema/args-name-has.exit
+++ b/tests/qapi-schema/args-name-has.exit
@@ -1 +1 @@
-0
+1
diff --git a/tests/qapi-schema/args-name-has.json b/tests/qapi-schema/args-name-has.json
index a2197de..4297549 100644
--- a/tests/qapi-schema/args-name-has.json
+++ b/tests/qapi-schema/args-name-has.json
@@ -1,6 +1,5 @@
 # C member name collision
-# FIXME - This parses, but fails to compile, because the C struct is given
-# two 'has_a' members, one from the flag for optional 'a', and the other
-# from member 'has-a'.  Either reject this at parse time, or munge the C
-# names to avoid the collision.
+# This would attempt to create two 'has_a' members of the C struct, one
+# from the flag for optional 'a', and the other from member 'has-a'.
+# TODO we could munge the optional flag name to avoid the collision.
 { 'command': 'oops', 'data': { '*a': 'str', 'has-a': 'str' } }
diff --git a/tests/qapi-schema/args-name-has.out b/tests/qapi-schema/args-name-has.out
index 5a18b6b..e69de29 100644
--- a/tests/qapi-schema/args-name-has.out
+++ b/tests/qapi-schema/args-name-has.out
@@ -1,6 +0,0 @@
-object :empty
-object :obj-oops-arg
-    member a: str optional=True
-    member has-a: str optional=False
-command oops :obj-oops-arg -> None
-   gen=True success_response=True
diff --git a/tests/qapi-schema/flat-union-clash-branch.err b/tests/qapi-schema/flat-union-clash-branch.err
index e69de29..e6b6294 100644
--- a/tests/qapi-schema/flat-union-clash-branch.err
+++ b/tests/qapi-schema/flat-union-clash-branch.err
@@ -0,0 +1 @@
+tests/qapi-schema/flat-union-clash-branch.json:13: Branch of union 'TestUnion' uses reserved name 'has-a'
diff --git a/tests/qapi-schema/flat-union-clash-branch.exit b/tests/qapi-schema/flat-union-clash-branch.exit
index 573541a..d00491f 100644
--- a/tests/qapi-schema/flat-union-clash-branch.exit
+++ b/tests/qapi-schema/flat-union-clash-branch.exit
@@ -1 +1 @@
-0
+1
diff --git a/tests/qapi-schema/flat-union-clash-branch.json b/tests/qapi-schema/flat-union-clash-branch.json
index c9f08e3..8efbcfd 100644
--- a/tests/qapi-schema/flat-union-clash-branch.json
+++ b/tests/qapi-schema/flat-union-clash-branch.json
@@ -1,8 +1,9 @@
 # Flat union branch name collision
-# FIXME: this parses, but then fails to compile due to a duplicate 'has_a'
+# This is rejected because the C struct would have duplicate 'has_a'
 # (one as the implicit flag for the optional base member, the other from
-# the C member for the branch name).  We should either reject the collision
-# at parse time, or munge the generated branch name to allow this to compile.
+# the C member for the branch name).
+# TODO: we should munge generated branch names to not collide with the
+# non-variant struct members.
 { 'enum': 'TestEnum',
   'data': [ 'has-a' ] }
 { 'struct': 'Base',
diff --git a/tests/qapi-schema/flat-union-clash-branch.out b/tests/qapi-schema/flat-union-clash-branch.out
index 1491081..e69de29 100644
--- a/tests/qapi-schema/flat-union-clash-branch.out
+++ b/tests/qapi-schema/flat-union-clash-branch.out
@@ -1,11 +0,0 @@
-object :empty
-object Base
-    member enum1: TestEnum optional=False
-    member a: str optional=True
-object Branch1
-    member string: str optional=False
-enum TestEnum ['has-a']
-object TestUnion
-    base Base
-    tag enum1
-    case has-a: Branch1
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index 81d19d0..1ca7e4f 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -105,11 +105,10 @@
             'sizes': ['size'],
             'any': ['any'] } }

-# Even if 'u' is forbidden as a struct member name, it should still be
-# valid as a type or union branch name. And although '*Kind' and '*List'
-# are forbidden as type names, they should not be forbidden as a member
-# or branch name.
-# TODO - 'has_*' should also be forbidden as a member name.
+# Even though 'u' and 'has_*' are forbidden as struct member names, they
+# should still be valid as a type or union branch name. And although
+# '*Kind' and '*List' are forbidden as type names, they should not be
+# forbidden as a member or branch name.
 { 'struct': 'has_a', 'data': { 'MyKind': 'int', 'MyList': ['int'] } }
 { 'union': 'u', 'data': { 'u': 'uint8', 'myKind': 'has_a',
                           'myList': 'has_a' } }
diff --git a/tests/qapi-schema/struct-member-u.err b/tests/qapi-schema/struct-member-u.err
index e69de29..5610310 100644
--- a/tests/qapi-schema/struct-member-u.err
+++ b/tests/qapi-schema/struct-member-u.err
@@ -0,0 +1 @@
+tests/qapi-schema/struct-member-u.json:6: Member of 'data' for struct 'Oops' uses reserved name 'u'
diff --git a/tests/qapi-schema/struct-member-u.exit b/tests/qapi-schema/struct-member-u.exit
index 573541a..d00491f 100644
--- a/tests/qapi-schema/struct-member-u.exit
+++ b/tests/qapi-schema/struct-member-u.exit
@@ -1 +1 @@
-0
+1
diff --git a/tests/qapi-schema/struct-member-u.json b/tests/qapi-schema/struct-member-u.json
index d72023d..a0e05b5 100644
--- a/tests/qapi-schema/struct-member-u.json
+++ b/tests/qapi-schema/struct-member-u.json
@@ -1,6 +1,6 @@
 # Potential C member name collision
-# FIXME - This parses and compiles, but would cause a collision if this
-# struct is later reworked to be part of a flat union, once unions hide
-# their tag values under a C union named 'u'. We should reject the use
-# of this identifier to reserve it for internal use.
+# We reject use of 'u' as a member name, to allow it for internal use in
+# putting union branch members in a separate namespace from QMP members.
+# This is true even for non-unions, because it is possible to convert a
+# struct to flat union while remaining backwards compatible in QMP.
 { 'struct': 'Oops', 'data': { 'u': 'str' } }
diff --git a/tests/qapi-schema/struct-member-u.out b/tests/qapi-schema/struct-member-u.out
index aa53e7f..e69de29 100644
--- a/tests/qapi-schema/struct-member-u.out
+++ b/tests/qapi-schema/struct-member-u.out
@@ -1,3 +0,0 @@
-object :empty
-object Oops
-    member u: str optional=False
-- 
2.4.3

  parent reply	other threads:[~2015-10-16  4:15 UTC|newest]

Thread overview: 57+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-10-16  4:15 [Qemu-devel] [PATCH v9 00/17] qapi collision reduction (post-introspection subset B') Eric Blake
2015-10-16  4:15 ` [Qemu-devel] [PATCH v9 01/17] qapi: Add tests for reserved name abuse Eric Blake
2015-10-19 16:05   ` Markus Armbruster
2015-10-20 16:23     ` Eric Blake
2015-10-21 12:08       ` Markus Armbruster
2015-10-16  4:15 ` [Qemu-devel] [PATCH v9 02/17] qapi: Reserve '*List' type names for arrays Eric Blake
2015-10-19 16:14   ` Markus Armbruster
2015-10-20 18:12     ` Eric Blake
2015-10-16  4:15 ` Eric Blake [this message]
2015-10-19 17:19   ` [Qemu-devel] [PATCH v9 03/17] qapi: Reserve 'u' and 'has[-_]*' member names Markus Armbruster
2015-10-20 21:29     ` Eric Blake
2015-10-21 13:08       ` Markus Armbruster
2015-10-16  4:15 ` [Qemu-devel] [PATCH v9 04/17] vnc: hoist allocation of VncBasicInfo to callers Eric Blake
2015-10-20  7:38   ` Markus Armbruster
2015-10-20  8:54     ` Gerd Hoffmann
2015-10-20 14:46       ` Markus Armbruster
2015-10-20 22:53         ` Eric Blake
2015-10-21 11:02           ` Markus Armbruster
2015-10-21 11:16           ` Daniel P. Berrange
2015-10-23 13:13             ` Markus Armbruster
2015-10-20 22:56     ` Eric Blake
2015-10-16  4:15 ` [Qemu-devel] [PATCH v9 05/17] qapi: Unbox base members Eric Blake
2015-10-16 19:12   ` [Qemu-devel] [PATCH v9 05.5/17] fixup to " Eric Blake
2015-10-20 12:09   ` [Qemu-devel] [PATCH v9 05/17] " Markus Armbruster
2015-10-20 16:08     ` Eric Blake
2015-10-21 13:34       ` Markus Armbruster
2015-10-21 21:16         ` Eric Blake
2015-10-22  6:28           ` Markus Armbruster
2015-10-23  1:50         ` Eric Blake
2015-10-23  6:26           ` Markus Armbruster
2015-10-16  4:15 ` [Qemu-devel] [PATCH v9 06/17] qapi-visit: Remove redundant functions for flat union base Eric Blake
2015-10-21 17:36   ` Markus Armbruster
2015-10-21 19:01     ` Eric Blake
2015-10-22  8:32       ` Markus Armbruster
2015-10-16  4:15 ` [Qemu-devel] [PATCH v9 07/17] qapi: Start converting to new qapi union layout Eric Blake
2015-10-22 13:54   ` Markus Armbruster
2015-10-22 14:09     ` Eric Blake
2015-10-22 14:44       ` Markus Armbruster
2015-10-16  4:15 ` [Qemu-devel] [PATCH v9 08/17] tests: Convert " Eric Blake
2015-10-22 14:01   ` Markus Armbruster
2015-10-22 14:22     ` Eric Blake
2015-10-22 14:57       ` Markus Armbruster
2015-10-16  4:15 ` [Qemu-devel] [PATCH v9 09/17] block: " Eric Blake
2015-10-16  4:15 ` [Qemu-devel] [PATCH v9 10/17] nbd: " Eric Blake
2015-10-16  4:15 ` [Qemu-devel] [PATCH v9 11/17] net: " Eric Blake
2015-10-16  4:15 ` [Qemu-devel] [PATCH v9 12/17] char: " Eric Blake
2015-10-16  4:15 ` [Qemu-devel] [PATCH v9 13/17] input: " Eric Blake
2015-10-16  4:15 ` [Qemu-devel] [PATCH v9 14/17] memory: " Eric Blake
2015-10-16  4:15 ` [Qemu-devel] [PATCH v9 15/17] tpm: " Eric Blake
2015-10-22 14:19   ` Markus Armbruster
2015-10-22 14:26     ` Eric Blake
2015-10-22 16:40       ` Eric Blake
2015-10-23  6:24         ` Markus Armbruster
2015-10-16  4:15 ` [Qemu-devel] [PATCH v9 16/17] qapi: Finish converting " Eric Blake
2015-10-22 14:50   ` Markus Armbruster
2015-10-16  4:15 ` [Qemu-devel] [PATCH v9 17/17] qapi: Simplify gen_struct_field() Eric Blake
2015-10-22 15:13 ` [Qemu-devel] [PATCH v9 00/17] qapi collision reduction (post-introspection subset B') Markus Armbruster

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1444968943-11254-4-git-send-email-eblake@redhat.com \
    --to=eblake@redhat.com \
    --cc=armbru@redhat.com \
    --cc=mdroth@linux.vnet.ibm.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.