diff mbox

[v10,04/25] qapi: Reserve '*List' type names for list types

Message ID 1445576998-2921-5-git-send-email-eblake@redhat.com
State New
Headers show

Commit Message

Eric Blake Oct. 23, 2015, 5:09 a.m. UTC
Type names ending in 'List' can clash with qapi list types in
generated C.  We don't currently use such names. It is easier to
outlaw them now than to worry about how to resolve such a clash
in the future. For precedence, see commit 4dc2e69, which did the
same for names ending in 'Kind' versus implicit enum types for
qapi unions.

Note that this only forbids explicit creation of new (non-array)
types or commands ending in 'List'; the parser already rejects
attempts to use ['intList'] as the type for an object member
(although 'intList' happens to be the C spelling for the qapi
type ['int'], that does not make it a recognized name in qapi).
Whether we later turn on support for multi-dimensional arrays
(via [['int']], not ['intList']) is a design decision best left
for another day.

Update the testsuite to match.

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

---
v10: improve commit message, including a retitle (qapi list types
may be JSON arrays, but they are C linked lists, not C arrays)
v9: new patch
---
 docs/qapi-code-gen.txt                  |  3 ++-
 scripts/qapi.py                         | 10 ++++------
 tests/qapi-schema/struct-name-list.err  |  1 +
 tests/qapi-schema/struct-name-list.exit |  2 +-
 tests/qapi-schema/struct-name-list.json |  6 +++---
 tests/qapi-schema/struct-name-list.out  |  3 ---
 6 files changed, 11 insertions(+), 14 deletions(-)

Comments

Markus Armbruster Oct. 23, 2015, 12:53 p.m. UTC | #1
Eric Blake <eblake@redhat.com> writes:

> Type names ending in 'List' can clash with qapi list types in
> generated C.  We don't currently use such names. It is easier to
> outlaw them now than to worry about how to resolve such a clash
> in the future. For precedence, see commit 4dc2e69, which did the
> same for names ending in 'Kind' versus implicit enum types for
> qapi unions.
>
> Note that this only forbids explicit creation of new (non-array)
> types or commands ending in 'List'; the parser already rejects
> attempts to use ['intList'] as the type for an object member
> (although 'intList' happens to be the C spelling for the qapi
> type ['int'], that does not make it a recognized name in qapi).
> Whether we later turn on support for multi-dimensional arrays
> (via [['int']], not ['intList']) is a design decision best left
> for another day.

I'd drop this paragraph, because I find it distracting.  Its first
sentence boils down to "we reject type names you didn't declare", but it
takes some mental effort to figure that out.  The second sentence talks
about a design detail of a possible future extension.  Neither is
necessary to understand this commit.

> Update the testsuite to match.
>
> Signed-off-by: Eric Blake <eblake@redhat.com>

Patch looks good.
diff mbox

Patch

diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
index 2afab20..c4264a8 100644
--- a/docs/qapi-code-gen.txt
+++ b/docs/qapi-code-gen.txt
@@ -106,7 +106,8 @@  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
 definitions should not end in 'Kind', as this namespace is used for
-creating implicit C enums for visiting union types.  Command names,
+creating implicit C enums for visiting union types, or in 'List', as
+this namespace is used for creating array types.  Command names,
 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,
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 3af4c2c..d53b5c4 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -390,10 +390,10 @@  def add_name(name, info, meta, implicit=False):
         raise QAPIExprError(info,
                             "%s '%s' is already defined"
                             % (all_names[name], name))
-    if not implicit and name.endswith('Kind'):
+    if not implicit and (name.endswith('Kind') or name.endswith('List')):
         raise QAPIExprError(info,
-                            "%s '%s' should not end in 'Kind'"
-                            % (meta, name))
+                            "%s '%s' should not end in '%s'"
+                            % (meta, name, name[-4:]))
     all_names[name] = meta


@@ -1196,9 +1196,7 @@  class QAPISchema(object):
         return name

     def _make_array_type(self, element_type, info):
-        # TODO fooList namespace is not reserved; user can create collisions,
-        # or abuse our type system with ['fooList'] for 2D array
-        name = element_type + 'List'
+        name = element_type + 'List'   # Use namespace reserved by add_name()
         if not self.lookup_type(name):
             self._def_entity(QAPISchemaArrayType(name, info, element_type))
         return name
diff --git a/tests/qapi-schema/struct-name-list.err b/tests/qapi-schema/struct-name-list.err
index e69de29..ee5b09b 100644
--- a/tests/qapi-schema/struct-name-list.err
+++ b/tests/qapi-schema/struct-name-list.err
@@ -0,0 +1 @@ 
+tests/qapi-schema/struct-name-list.json:5: struct 'FooList' should not end in 'List'
diff --git a/tests/qapi-schema/struct-name-list.exit b/tests/qapi-schema/struct-name-list.exit
index 573541a..d00491f 100644
--- a/tests/qapi-schema/struct-name-list.exit
+++ b/tests/qapi-schema/struct-name-list.exit
@@ -1 +1 @@ 
-0
+1
diff --git a/tests/qapi-schema/struct-name-list.json b/tests/qapi-schema/struct-name-list.json
index 8ad38e6..98d53bf 100644
--- a/tests/qapi-schema/struct-name-list.json
+++ b/tests/qapi-schema/struct-name-list.json
@@ -1,5 +1,5 @@ 
 # Potential C name collision
-# FIXME - This parses and compiles on its own, but prevents the user from
-# creating a type named 'Foo' and using ['Foo'] for an array.  We should
-# reject the use of any non-array type names ending in 'List'.
+# We reserve names ending in 'List' for use by array types.
+# TODO - we could choose array names to avoid collision with user types,
+# in order to let this compile
 { 'struct': 'FooList', 'data': { 's': 'str' } }
diff --git a/tests/qapi-schema/struct-name-list.out b/tests/qapi-schema/struct-name-list.out
index 0406bfe..e69de29 100644
--- a/tests/qapi-schema/struct-name-list.out
+++ b/tests/qapi-schema/struct-name-list.out
@@ -1,3 +0,0 @@ 
-object :empty
-object FooList
-    member s: str optional=False