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 v11 20/28] qapi: Forbid case-insensitive clashes
Date: Tue, 10 Nov 2015 23:51:22 -0700	[thread overview]
Message-ID: <1447224690-9743-21-git-send-email-eblake@redhat.com> (raw)
In-Reply-To: <1447224690-9743-1-git-send-email-eblake@redhat.com>

In general, designing user interfaces that rely on case
distinction is poor practice.  Another benefit of enforcing
a restriction against case-insensitive clashes is that we
no longer have to worry about the situation of enum values
that could be distinguished by case if mapped by c_name(),
but which cannot be distinguished when mapped to C as
ALL_CAPS by camel_to_upper().  Thus, having the generator
look for case collisions up front will prevent developers
from worrying whether different munging rules for member
names compared to enum values as a discriminator will cause
any problems in qapi unions.

There is also the possibility that we may want to add a
future extension to QMP of teaching it to be case-insensitive
(the user could request command 'Quit' instead of 'quit', or
could spell a struct field as 'CPU' instead of 'cpu').  But
for that to be a practical extension, we cannot break
backwards compatibility with any existing struct that was
already relying on case sensitivity.  Fortunately, after the
previous patch cleaned up CpuInfo, there are no such existing
qapi structs.  Of course, the idea of a future extension is
not as strong of a reason to make the change.

At any rate, it is easier to be strict now, and relax things
later if we find a reason to need case-sensitive QMP members,
than it would be to wish we had the restriction in place.

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

---
v11: rebase to latest, don't focus so hard on future case-insensitive
extensions, adjust commit message
v10: new patch
---
 docs/qapi-code-gen.txt                 | 3 +++
 scripts/qapi.py                        | 4 ++--
 tests/Makefile                         | 1 +
 tests/qapi-schema/args-case-clash.err  | 1 +
 tests/qapi-schema/args-case-clash.exit | 1 +
 tests/qapi-schema/args-case-clash.json | 4 ++++
 tests/qapi-schema/args-case-clash.out  | 0
 7 files changed, 12 insertions(+), 2 deletions(-)
 create mode 100644 tests/qapi-schema/args-case-clash.err
 create mode 100644 tests/qapi-schema/args-case-clash.exit
 create mode 100644 tests/qapi-schema/args-case-clash.json
 create mode 100644 tests/qapi-schema/args-case-clash.out

diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
index f9fa6f3..54a6a7b 100644
--- a/docs/qapi-code-gen.txt
+++ b/docs/qapi-code-gen.txt
@@ -102,6 +102,9 @@ single-dimension array of that type; multi-dimension arrays are not
 directly supported (although an array of a complex struct that
 contains an array member is possible).

+Client JSON Protocol is case-sensitive.  However, the generator
+rejects attempts to create entities that differ only in case.
+
 Types, commands, and events share a common namespace.  Therefore,
 generally speaking, type definitions should always use CamelCase for
 user-defined type names, while built-in types are lowercase. Type
diff --git a/scripts/qapi.py b/scripts/qapi.py
index d0f2308..ed7a32b 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -1040,7 +1040,7 @@ class QAPISchemaObjectTypeMember(object):
         assert self.type

     def check_clash(self, info, seen):
-        cname = c_name(self.name)
+        cname = c_name(self.name).upper()
         if cname in seen:
             raise QAPIExprError(info,
                                 "%s collides with %s"
@@ -1085,7 +1085,7 @@ class QAPISchemaObjectTypeVariants(object):

     def check(self, schema, seen):
         if not self.tag_member:    # flat union
-            self.tag_member = seen[c_name(self.tag_name)]
+            self.tag_member = seen[c_name(self.tag_name).upper()]
             assert self.tag_name == self.tag_member.name
         assert isinstance(self.tag_member.type, QAPISchemaEnumType)
         for v in self.variants:
diff --git a/tests/Makefile b/tests/Makefile
index c84c6cb..d1c6817 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -239,6 +239,7 @@ qapi-schema += args-alternate.json
 qapi-schema += args-any.json
 qapi-schema += args-array-empty.json
 qapi-schema += args-array-unknown.json
+qapi-schema += args-case-clash.json
 qapi-schema += args-int.json
 qapi-schema += args-invalid.json
 qapi-schema += args-member-array-bad.json
diff --git a/tests/qapi-schema/args-case-clash.err b/tests/qapi-schema/args-case-clash.err
new file mode 100644
index 0000000..0fafe75
--- /dev/null
+++ b/tests/qapi-schema/args-case-clash.err
@@ -0,0 +1 @@
+tests/qapi-schema/args-case-clash.json:4: 'A' (parameter of oops) collides with 'a' (parameter of oops)
diff --git a/tests/qapi-schema/args-case-clash.exit b/tests/qapi-schema/args-case-clash.exit
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/tests/qapi-schema/args-case-clash.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/args-case-clash.json b/tests/qapi-schema/args-case-clash.json
new file mode 100644
index 0000000..e6f0625
--- /dev/null
+++ b/tests/qapi-schema/args-case-clash.json
@@ -0,0 +1,4 @@
+# C member name collision
+# Reject members that clash case-insensitively, even though our mapping to
+# C names preserves case.
+{ 'command': 'oops', 'data': { 'a': 'str', 'A': 'int' } }
diff --git a/tests/qapi-schema/args-case-clash.out b/tests/qapi-schema/args-case-clash.out
new file mode 100644
index 0000000..e69de29
-- 
2.4.3

  parent reply	other threads:[~2015-11-11  6:52 UTC|newest]

Thread overview: 72+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-11-11  6:51 [Qemu-devel] [PATCH v11 00/28] qapi member collision, alternate layout (post-introspection cleanups, subset D) Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 01/28] qapi: Track simple union tag in object.local_members Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 02/28] qapi-types: Consolidate gen_struct() and gen_union() Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 03/28] qapi-types: Simplify gen_struct_field[s] Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 04/28] qapi: Drop obsolete tag value collision assertions Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 05/28] qapi: Simplify QAPISchemaObjectTypeMember.check() Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 06/28] qapi: Clean up after previous commit Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 07/28] qapi: Fix up commit 7618b91's clash sanity checking change Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 08/28] qapi: Eliminate QAPISchemaObjectType.check() variable members Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 09/28] qapi: Factor out QAPISchemaObjectTypeMember.check_clash() Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 10/28] qapi: Simplify QAPISchemaObjectTypeVariants.check() Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 11/28] qapi: Check for qapi collisions of flat union branches Eric Blake
2015-11-11 13:42   ` Markus Armbruster
2015-11-11 15:49     ` Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 12/28] qapi: Factor out QAPISchemaObjectType.check_clash() Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 13/28] qapi: Hoist tag collision check to Variants.check() Eric Blake
2015-11-11 13:56   ` Markus Armbruster
2015-11-11 16:11     ` Eric Blake
2015-11-11 17:03       ` Markus Armbruster
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 14/28] qapi: Remove outdated tests related to QMP/branch collisions Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 15/28] qapi: Track owner of each object member Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 16/28] qapi: Detect collisions in C member names Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 17/28] cpu: Convert CpuInfo into flat union Eric Blake
2015-11-11 14:13   ` Markus Armbruster
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 18/28] qerror: more error_setg() usage Eric Blake
2015-11-11 13:26   ` Andreas Färber
2015-11-11 14:21   ` Markus Armbruster
2015-11-11 14:23     ` Andreas Färber
2015-11-11 15:51       ` Eric Blake
2015-11-11 16:19     ` Eric Blake
2015-11-11 17:31       ` Markus Armbruster
2015-11-11 17:44         ` Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 19/28] qapi: Change munging of CamelCase enum values Eric Blake
2015-11-11 13:29   ` Andreas Färber
2015-11-11 14:50   ` Markus Armbruster
2015-11-11 16:03     ` Eric Blake
2015-11-11 17:11       ` Markus Armbruster
2015-11-12  8:34         ` Gerd Hoffmann
2015-11-12 11:16           ` Markus Armbruster
2015-11-12  8:29       ` Gerd Hoffmann
2015-11-11 16:06     ` Eric Blake
2015-11-13 17:46   ` Eric Blake
2015-11-13 18:13     ` Markus Armbruster
2015-11-13 21:37       ` Eric Blake
2015-11-16 14:30         ` Markus Armbruster
2015-11-11  6:51 ` Eric Blake [this message]
2015-11-11 14:53   ` [Qemu-devel] [PATCH v11 20/28] qapi: Forbid case-insensitive clashes Markus Armbruster
2015-11-13  5:32     ` Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 21/28] qapi: Convert qtype_code into qapi enum type Eric Blake
2015-11-11 16:42   ` Markus Armbruster
2015-11-11 17:03     ` Eric Blake
2015-11-12 13:16       ` Markus Armbruster
2015-11-18  6:27         ` Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 22/28] qapi: Simplify visiting of alternate types Eric Blake
2015-11-12 14:21   ` Markus Armbruster
2015-11-12 15:54   ` Markus Armbruster
2015-11-13 23:54   ` Eric Blake
2015-11-16 14:31     ` Markus Armbruster
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 23/28] qapi: Fix alternates that accept 'number' but not 'int' Eric Blake
2015-11-12 15:01   ` Markus Armbruster
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 24/28] qapi: Add positive tests to qapi-schema-test Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 25/28] qapi: Simplify visits of optional fields Eric Blake
2015-11-12 15:11   ` Markus Armbruster
2015-11-12 15:30     ` Eric Blake
2015-11-12 16:20       ` Markus Armbruster
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 26/28] qapi: Move duplicate member checks to schema check() Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 27/28] qapi: Move duplicate enum value " Eric Blake
2015-11-12 15:46   ` Markus Armbruster
2015-11-12 16:08     ` Eric Blake
2015-11-18  6:48     ` Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 28/28] qapi: Detect base class loops Eric Blake
2015-11-12 16:06   ` 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=1447224690-9743-21-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.