All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v3 00/14] Fix qapi mangling of downstream names
@ 2015-05-05 12:30 Eric Blake
  2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 01/14] qapi: Fix C identifiers generated for names containing '.' Eric Blake
                   ` (14 more replies)
  0 siblings, 15 replies; 25+ messages in thread
From: Eric Blake @ 2015-05-05 12:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, akong, berto, armbru, mdroth

This series makes it possible to use downstream extensions
(such as __com.redhat_xyz) and temporary names (such as x-foo)
in every position possible in QAPI schemes, with added tests
that the generated code still compiles.

There's still some things we could do to the qapi generator,
such as normalizing struct member names and C manglings and
creating named implicit types up front on the initial parse
rather than multiple times in each backend.  But that should
wait until existing pending patches have landed, to minimize
rebase churn.

v2 was here:
https://lists.gnu.org/archive/html/qemu-devel/2015-04/msg01300.html

v3 includes several more of Markus' original RFC series, splits
up my work into smaller pieces, incorporates fixes suggested by
Markus, and rebases on top of the pending v8 qapi drop nested
structs series.  The series has changed enough from v2 that it
is not worth showing git backport-diff statistics (as only patch
1 survived intact).

Eric Blake (8):
  qapi: Rename identical c_fun()/c_var() into c_name()
  qapi: Make c_type() consistently convert qapi names
  qapi: Support downstream enums
  qapi: Support downstream structs
  qapi: Support downstream simple unions
  qapi: Support downstream flat unions
  qapi: Support downstream alternates
  qapi: Support downstream events and commands

Markus Armbruster (6):
  qapi: Fix C identifiers generated for names containing '.'
  qapi: Rename _generate_enum_string() to camel_to_upper()
  qapi: Rename generate_enum_full_value() to c_enum_const()
  qapi: Simplify c_enum_const()
  qapi: Use c_enum_const() in generate_alternate_qtypes()
  qapi: Move camel_to_upper(), c_enum_const() to closely related code

 scripts/qapi-commands.py                | 51 ++++++++----------
 scripts/qapi-event.py                   | 15 +++---
 scripts/qapi-types.py                   | 44 +++++++--------
 scripts/qapi-visit.py                   | 54 ++++++++++---------
 scripts/qapi.py                         | 96 ++++++++++++++++-----------------
 tests/qapi-schema/qapi-schema-test.json | 20 +++++++
 tests/qapi-schema/qapi-schema-test.out  | 21 ++++++--
 tests/test-qmp-commands.c               | 15 ++++++
 8 files changed, 179 insertions(+), 137 deletions(-)

-- 
2.1.0

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [Qemu-devel] [PATCH v3 01/14] qapi: Fix C identifiers generated for names containing '.'
  2015-05-05 12:30 [Qemu-devel] [PATCH v3 00/14] Fix qapi mangling of downstream names Eric Blake
@ 2015-05-05 12:30 ` Eric Blake
  2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 02/14] qapi: Rename identical c_fun()/c_var() into c_name() Eric Blake
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 25+ messages in thread
From: Eric Blake @ 2015-05-05 12:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, akong, berto, armbru, mdroth

From: Markus Armbruster <armbru@redhat.com>

c_fun() maps '.' to '_', c_var() doesn't.  Nothing prevents '.' in
QAPI names that get passed to c_var().

Which QAPI names get passed to c_fun(), to c_var(), or to both is not
obvious.  Names of command parameters and struct type members get
passed to c_var().

c_var() strips a leading '*', but this cannot happen.  c_fun()
doesn't.

Fix c_var() to work exactly like c_fun().

Perhaps they should be replaced by a single mapping function.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
[add 'import string']
Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
---
 scripts/qapi.py | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index edfaf9e..ca1adf2 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -15,6 +15,7 @@ import re
 from ordereddict import OrderedDict
 import os
 import sys
+import string

 builtin_types = {
     'str':      'QTYPE_QSTRING',
@@ -752,6 +753,8 @@ def camel_case(name):
             new_name += ch.lower()
     return new_name

+c_var_trans = string.maketrans('.-', '__')
+
 def c_var(name, protect=True):
     # ANSI X3J11/88-090, 3.1.1
     c89_words = set(['auto', 'break', 'case', 'char', 'const', 'continue',
@@ -781,10 +784,10 @@ def c_var(name, protect=True):
     polluted_words = set(['unix', 'errno'])
     if protect and (name in c89_words | c99_words | c11_words | gcc_words | cpp_words | polluted_words):
         return "q_" + name
-    return name.replace('-', '_').lstrip("*")
+    return name.translate(c_var_trans)

 def c_fun(name, protect=True):
-    return c_var(name, protect).replace('.', '_')
+    return c_var(name, protect)

 def c_list_type(name):
     return '%sList' % name
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [Qemu-devel] [PATCH v3 02/14] qapi: Rename identical c_fun()/c_var() into c_name()
  2015-05-05 12:30 [Qemu-devel] [PATCH v3 00/14] Fix qapi mangling of downstream names Eric Blake
  2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 01/14] qapi: Fix C identifiers generated for names containing '.' Eric Blake
@ 2015-05-05 12:30 ` Eric Blake
  2015-05-07  7:39   ` Markus Armbruster
  2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 03/14] qapi: Rename _generate_enum_string() to camel_to_upper() Eric Blake
                   ` (12 subsequent siblings)
  14 siblings, 1 reply; 25+ messages in thread
From: Eric Blake @ 2015-05-05 12:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, akong, berto, armbru, mdroth

Now that the two functions are identical, we only need one of them,
and we might as well give it a more descriptive name.  Basically,
the function serves as the translation from a QAPI name into a
(portion of a) C identifier, without regards to whether it is a
variable or function name.

Signed-off-by: Eric Blake <eblake@redhat.com>
---
 scripts/qapi-commands.py | 35 ++++++++++++++++++-----------------
 scripts/qapi-event.py    | 10 +++++-----
 scripts/qapi-types.py    |  8 ++++----
 scripts/qapi-visit.py    | 10 +++++-----
 scripts/qapi.py          | 11 ++++-------
 5 files changed, 36 insertions(+), 38 deletions(-)

diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index 93e43f0..8c125ca 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -31,12 +31,13 @@ def generate_command_decl(name, args, ret_type):
     for argname, argtype, optional in parse_args(args):
         argtype = c_type(argtype, is_param=True)
         if optional:
-            arglist += "bool has_%s, " % c_var(argname)
-        arglist += "%s %s, " % (argtype, c_var(argname))
+            arglist += "bool has_%s, " % c_name(argname)
+        arglist += "%s %s, " % (argtype, c_name(argname))
     return mcgen('''
 %(ret_type)s qmp_%(name)s(%(args)sError **errp);
 ''',
-                 ret_type=c_type(ret_type), name=c_fun(name), args=arglist).strip()
+                 ret_type=c_type(ret_type), name=c_name(name),
+                 args=arglist).strip()

 def gen_err_check(errvar):
     if errvar:
@@ -55,14 +56,14 @@ def gen_sync_call(name, args, ret_type, indent=0):
         retval = "retval = "
     for argname, argtype, optional in parse_args(args):
         if optional:
-            arglist += "has_%s, " % c_var(argname)
-        arglist += "%s, " % (c_var(argname))
+            arglist += "has_%s, " % c_name(argname)
+        arglist += "%s, " % (c_name(argname))
     push_indent(indent)
     ret = mcgen('''
 %(retval)sqmp_%(name)s(%(args)s&local_err);

 ''',
-                name=c_fun(name), args=arglist, retval=retval).rstrip()
+                name=c_name(name), args=arglist, retval=retval).rstrip()
     if ret_type:
         ret += "\n" + gen_err_check('local_err')
         ret += "\n" + mcgen(''''
@@ -76,7 +77,7 @@ def gen_sync_call(name, args, ret_type, indent=0):
 def gen_marshal_output_call(name, ret_type):
     if not ret_type:
         return ""
-    return "qmp_marshal_output_%s(retval, ret, &local_err);" % c_fun(name)
+    return "qmp_marshal_output_%s(retval, ret, &local_err);" % c_name(name)

 def gen_visitor_input_containers_decl(args, obj):
     ret = ""
@@ -101,17 +102,17 @@ def gen_visitor_input_vars_decl(args):
             ret += mcgen('''
 bool has_%(argname)s = false;
 ''',
-                         argname=c_var(argname))
+                         argname=c_name(argname))
         if is_c_ptr(argtype):
             ret += mcgen('''
 %(argtype)s %(argname)s = NULL;
 ''',
-                         argname=c_var(argname), argtype=c_type(argtype))
+                         argname=c_name(argname), argtype=c_type(argtype))
         else:
             ret += mcgen('''
 %(argtype)s %(argname)s = {0};
 ''',
-                         argname=c_var(argname), argtype=c_type(argtype))
+                         argname=c_name(argname), argtype=c_type(argtype))

     pop_indent()
     return ret.rstrip()
@@ -144,17 +145,17 @@ v = qmp_input_get_visitor(mi);
             ret += mcgen('''
 visit_optional(v, &has_%(c_name)s, "%(name)s", %(errp)s);
 ''',
-                         c_name=c_var(argname), name=argname, errp=errparg)
+                         c_name=c_name(argname), name=argname, errp=errparg)
             ret += gen_err_check(errarg)
             ret += mcgen('''
 if (has_%(c_name)s) {
 ''',
-                         c_name=c_var(argname))
+                         c_name=c_name(argname))
             push_indent()
         ret += mcgen('''
 %(visitor)s(v, &%(c_name)s, "%(name)s", %(errp)s);
 ''',
-                     c_name=c_var(argname), name=argname, argtype=argtype,
+                     c_name=c_name(argname), name=argname, argtype=argtype,
                      visitor=type_visitor(argtype), errp=errparg)
         ret += gen_err_check(errarg)
         if optional:
@@ -198,16 +199,16 @@ out:
     qapi_dealloc_visitor_cleanup(md);
 }
 ''',
-                c_ret_type=c_type(ret_type), c_name=c_fun(name),
+                c_ret_type=c_type(ret_type), c_name=c_name(name),
                 visitor=type_visitor(ret_type))

     return ret

 def gen_marshal_input_decl(name, args, ret_type, middle_mode):
     if middle_mode:
-        return 'int qmp_marshal_input_%s(Monitor *mon, const QDict *qdict, QObject **ret)' % c_fun(name)
+        return 'int qmp_marshal_input_%s(Monitor *mon, const QDict *qdict, QObject **ret)' % c_name(name)
     else:
-        return 'static void qmp_marshal_input_%s(QDict *args, QObject **ret, Error **errp)' % c_fun(name)
+        return 'static void qmp_marshal_input_%s(QDict *args, QObject **ret, Error **errp)' % c_name(name)



@@ -304,7 +305,7 @@ def gen_registry(commands):
         registry += mcgen('''
 qmp_register_command("%(name)s", qmp_marshal_input_%(c_name)s, %(opts)s);
 ''',
-                     name=cmd['command'], c_name=c_fun(cmd['command']),
+                     name=cmd['command'], c_name=c_name(cmd['command']),
                      opts=options)
     pop_indent()
     ret = mcgen('''
diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py
index 47dc041..c4612e3 100644
--- a/scripts/qapi-event.py
+++ b/scripts/qapi-event.py
@@ -17,17 +17,17 @@ import getopt
 import errno

 def _generate_event_api_name(event_name, params):
-    api_name = "void qapi_event_send_%s(" % c_fun(event_name).lower();
+    api_name = "void qapi_event_send_%s(" % c_name(event_name).lower();
     l = len(api_name)

     if params:
         for argname, argentry, optional in parse_args(params):
             if optional:
-                api_name += "bool has_%s,\n" % c_var(argname)
+                api_name += "bool has_%s,\n" % c_name(argname)
                 api_name += "".ljust(l)

             api_name += "%s %s,\n" % (c_type(argentry, is_param=True),
-                                      c_var(argname))
+                                      c_name(argname))
             api_name += "".ljust(l)

     api_name += "Error **errp)"
@@ -98,7 +98,7 @@ def generate_event_implement(api_name, event_name, params):
                 ret += mcgen("""
     if (has_%(var)s) {
 """,
-                             var = c_var(argname))
+                             var = c_name(argname))
                 push_indent()

             if argentry == "str":
@@ -113,7 +113,7 @@ def generate_event_implement(api_name, event_name, params):
     }
 """,
                          var_type = var_type,
-                         var = c_var(argname),
+                         var = c_name(argname),
                          type = type_name(argentry),
                          name = argname)

diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 2bf8145..e74cabe 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -68,11 +68,11 @@ def generate_struct_fields(members):
             ret += mcgen('''
     bool has_%(c_name)s;
 ''',
-                         c_name=c_var(argname))
+                         c_name=c_name(argname))
         ret += mcgen('''
     %(c_type)s %(c_name)s;
 ''',
-                     c_type=c_type(argentry), c_name=c_var(argname))
+                     c_type=c_type(argentry), c_name=c_name(argname))

     return ret

@@ -184,7 +184,7 @@ const int %(name)s_qtypes[QTYPE_MAX] = {
 ''',
         qtype = qtype,
         abbrev = de_camel_case(name).upper(),
-        enum = c_fun(de_camel_case(key),False).upper())
+        enum = c_name(de_camel_case(key),False).upper())

     ret += mcgen('''
 };
@@ -221,7 +221,7 @@ struct %(name)s
         %(c_type)s %(c_name)s;
 ''',
                      c_type=c_type(typeinfo[key]),
-                     c_name=c_fun(key))
+                     c_name=c_name(key))

     ret += mcgen('''
     };
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 0e67b33..ba623b1 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -66,7 +66,7 @@ if (err) {
     goto out;
 }
 ''',
-                     type=type_name(base), c_name=c_var('base'))
+                     type=type_name(base), c_name=c_name('base'))

     for argname, argentry, optional in parse_args(members):
         if optional:
@@ -74,13 +74,13 @@ if (err) {
 visit_optional(m, &(*obj)->has_%(c_name)s, "%(name)s", &err);
 if (!err && (*obj)->has_%(c_name)s) {
 ''',
-                         c_name=c_var(argname), name=argname)
+                         c_name=c_name(argname), name=argname)
             push_indent()

         ret += mcgen('''
 visit_type_%(type)s(m, &(*obj)->%(c_name)s, "%(name)s", &err);
 ''',
-                     type=type_name(argentry), c_name=c_var(argname),
+                     type=type_name(argentry), c_name=c_name(argname),
                      name=argname)

         if optional:
@@ -222,7 +222,7 @@ void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **e
 ''',
                 enum_full_value = enum_full_value,
                 c_type = type_name(members[key]),
-                c_name = c_fun(key))
+                c_name = c_name(key))

     ret += mcgen('''
     default:
@@ -323,7 +323,7 @@ void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **e
 ''',
                 enum_full_value = enum_full_value,
                 c_type=type_name(members[key]),
-                c_name=c_fun(key))
+                c_name=c_name(key))

     ret += mcgen('''
         default:
diff --git a/scripts/qapi.py b/scripts/qapi.py
index ca1adf2..2431327 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -753,9 +753,9 @@ def camel_case(name):
             new_name += ch.lower()
     return new_name

-c_var_trans = string.maketrans('.-', '__')
+c_name_trans = string.maketrans('.-', '__')

-def c_var(name, protect=True):
+def c_name(name, protect=True):
     # ANSI X3J11/88-090, 3.1.1
     c89_words = set(['auto', 'break', 'case', 'char', 'const', 'continue',
                      'default', 'do', 'double', 'else', 'enum', 'extern', 'float',
@@ -784,10 +784,7 @@ def c_var(name, protect=True):
     polluted_words = set(['unix', 'errno'])
     if protect and (name in c89_words | c99_words | c11_words | gcc_words | cpp_words | polluted_words):
         return "q_" + name
-    return name.translate(c_var_trans)
-
-def c_fun(name, protect=True):
-    return c_var(name, protect)
+    return name.translate(c_name_trans)

 def c_list_type(name):
     return '%sList' % name
@@ -945,7 +942,7 @@ def guardend(name):
 # ENUM_NAME -> ENUM_NAME, ENUM_NAME1 -> ENUM_NAME1, ENUM_Name2 -> ENUM_NAME2
 # ENUM24_Name -> ENUM24_NAME
 def _generate_enum_string(value):
-    c_fun_str = c_fun(value, False)
+    c_fun_str = c_name(value, False)
     if value.isupper():
         return c_fun_str

-- 
2.1.0

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [Qemu-devel] [PATCH v3 03/14] qapi: Rename _generate_enum_string() to camel_to_upper()
  2015-05-05 12:30 [Qemu-devel] [PATCH v3 00/14] Fix qapi mangling of downstream names Eric Blake
  2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 01/14] qapi: Fix C identifiers generated for names containing '.' Eric Blake
  2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 02/14] qapi: Rename identical c_fun()/c_var() into c_name() Eric Blake
@ 2015-05-05 12:30 ` Eric Blake
  2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 04/14] qapi: Rename generate_enum_full_value() to c_enum_const() Eric Blake
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 25+ messages in thread
From: Eric Blake @ 2015-05-05 12:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, akong, berto, armbru, mdroth

From: Markus Armbruster <armbru@redhat.com>

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
---
 scripts/qapi.py | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 2431327..d9ed73a 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -538,7 +538,7 @@ def check_union(expr, expr_info):

         # Otherwise, check for conflicts in the generated enum
         else:
-            c_key = _generate_enum_string(key)
+            c_key = camel_to_upper(key)
             if c_key in values:
                 raise QAPIExprError(expr_info,
                                     "Union '%s' member '%s' clashes with '%s'"
@@ -556,7 +556,7 @@ def check_alternate(expr, expr_info):
         check_name(expr_info, "Member of alternate '%s'" % name, key)

         # Check for conflicts in the generated enum
-        c_key = _generate_enum_string(key)
+        c_key = camel_to_upper(key)
         if c_key in values:
             raise QAPIExprError(expr_info,
                                 "Alternate '%s' member '%s' clashes with '%s'"
@@ -587,7 +587,7 @@ def check_enum(expr, expr_info):
     for member in members:
         check_name(expr_info, "Member of enum '%s'" %name, member,
                    enum_member=True)
-        key = _generate_enum_string(member)
+        key = camel_to_upper(member)
         if key in values:
             raise QAPIExprError(expr_info,
                                 "Enum '%s' member '%s' clashes with '%s'"
@@ -941,7 +941,7 @@ def guardend(name):
 # ENUMName -> ENUM_NAME, EnumName1 -> ENUM_NAME1
 # ENUM_NAME -> ENUM_NAME, ENUM_NAME1 -> ENUM_NAME1, ENUM_Name2 -> ENUM_NAME2
 # ENUM24_Name -> ENUM24_NAME
-def _generate_enum_string(value):
+def camel_to_upper(value):
     c_fun_str = c_name(value, False)
     if value.isupper():
         return c_fun_str
@@ -961,6 +961,6 @@ def _generate_enum_string(value):
     return new_name.lstrip('_').upper()

 def generate_enum_full_value(enum_name, enum_value):
-    abbrev_string = _generate_enum_string(enum_name)
-    value_string = _generate_enum_string(enum_value)
+    abbrev_string = camel_to_upper(enum_name)
+    value_string = camel_to_upper(enum_value)
     return "%s_%s" % (abbrev_string, value_string)
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [Qemu-devel] [PATCH v3 04/14] qapi: Rename generate_enum_full_value() to c_enum_const()
  2015-05-05 12:30 [Qemu-devel] [PATCH v3 00/14] Fix qapi mangling of downstream names Eric Blake
                   ` (2 preceding siblings ...)
  2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 03/14] qapi: Rename _generate_enum_string() to camel_to_upper() Eric Blake
@ 2015-05-05 12:30 ` Eric Blake
  2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 05/14] qapi: Simplify c_enum_const() Eric Blake
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 25+ messages in thread
From: Eric Blake @ 2015-05-05 12:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, akong, berto, armbru, mdroth

From: Markus Armbruster <armbru@redhat.com>

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
---
 scripts/qapi-event.py | 5 ++---
 scripts/qapi-types.py | 6 +++---
 scripts/qapi-visit.py | 4 ++--
 scripts/qapi.py       | 6 +++---
 4 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py
index c4612e3..a7e0033 100644
--- a/scripts/qapi-event.py
+++ b/scripts/qapi-event.py
@@ -177,7 +177,7 @@ typedef enum %(event_enum_name)s
                       event_enum_name = event_enum_name)

     # append automatically generated _MAX value
-    enum_max_value = generate_enum_full_value(event_enum_name, "MAX")
+    enum_max_value = c_enum_const(event_enum_name, "MAX")
     enum_values = event_enum_values + [ enum_max_value ]

     i = 0
@@ -343,8 +343,7 @@ for expr in exprs:
         fdecl.write(ret)

         # We need an enum value per event
-        event_enum_value = generate_enum_full_value(event_enum_name,
-                                                    event_name)
+        event_enum_value = c_enum_const(event_enum_name, event_name)
         ret = generate_event_implement(api_name, event_name, params)
         fdef.write(ret)

diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index e74cabe..6ca48c1 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -118,13 +118,13 @@ const char *%(name)s_lookup[] = {
                          name=name)
     i = 0
     for value in values:
-        index = generate_enum_full_value(name, value)
+        index = c_enum_const(name, value)
         ret += mcgen('''
     [%(index)s] = "%(value)s",
 ''',
                      index = index, value = value)

-    max_index = generate_enum_full_value(name, 'MAX')
+    max_index = c_enum_const(name, 'MAX')
     ret += mcgen('''
     [%(max_index)s] = NULL,
 };
@@ -150,7 +150,7 @@ typedef enum %(name)s

     i = 0
     for value in enum_values:
-        enum_full_value = generate_enum_full_value(name, value)
+        enum_full_value = c_enum_const(name, value)
         enum_decl += mcgen('''
     %(enum_full_value)s = %(i)d,
 ''',
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index ba623b1..0368e62 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -214,7 +214,7 @@ void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **e
             or find_union(members[key])
             or find_enum(members[key])), "Invalid alternate member"

-        enum_full_value = generate_enum_full_value(disc_type, key)
+        enum_full_value = c_enum_const(disc_type, key)
         ret += mcgen('''
     case %(enum_full_value)s:
         visit_type_%(c_type)s(m, &(*obj)->%(c_name)s, name, &err);
@@ -315,7 +315,7 @@ void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **e
         else:
             fmt = 'visit_type_implicit_%(c_type)s(m, &(*obj)->%(c_name)s, &err);'

-        enum_full_value = generate_enum_full_value(disc_type, key)
+        enum_full_value = c_enum_const(disc_type, key)
         ret += mcgen('''
         case %(enum_full_value)s:
             ''' + fmt + '''
diff --git a/scripts/qapi.py b/scripts/qapi.py
index d9ed73a..b3628fd 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -960,7 +960,7 @@ def camel_to_upper(value):
         new_name += c
     return new_name.lstrip('_').upper()

-def generate_enum_full_value(enum_name, enum_value):
-    abbrev_string = camel_to_upper(enum_name)
-    value_string = camel_to_upper(enum_value)
+def c_enum_const(type_name, const_name):
+    abbrev_string = camel_to_upper(type_name)
+    value_string = camel_to_upper(const_name)
     return "%s_%s" % (abbrev_string, value_string)
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [Qemu-devel] [PATCH v3 05/14] qapi: Simplify c_enum_const()
  2015-05-05 12:30 [Qemu-devel] [PATCH v3 00/14] Fix qapi mangling of downstream names Eric Blake
                   ` (3 preceding siblings ...)
  2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 04/14] qapi: Rename generate_enum_full_value() to c_enum_const() Eric Blake
@ 2015-05-05 12:30 ` Eric Blake
  2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 06/14] qapi: Use c_enum_const() in generate_alternate_qtypes() Eric Blake
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 25+ messages in thread
From: Eric Blake @ 2015-05-05 12:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, akong, berto, armbru, mdroth

From: Markus Armbruster <armbru@redhat.com>

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
---
 scripts/qapi.py | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index b3628fd..9209fd5 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -961,6 +961,4 @@ def camel_to_upper(value):
     return new_name.lstrip('_').upper()

 def c_enum_const(type_name, const_name):
-    abbrev_string = camel_to_upper(type_name)
-    value_string = camel_to_upper(const_name)
-    return "%s_%s" % (abbrev_string, value_string)
+    return camel_to_upper(type_name + '_' + const_name)
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [Qemu-devel] [PATCH v3 06/14] qapi: Use c_enum_const() in generate_alternate_qtypes()
  2015-05-05 12:30 [Qemu-devel] [PATCH v3 00/14] Fix qapi mangling of downstream names Eric Blake
                   ` (4 preceding siblings ...)
  2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 05/14] qapi: Simplify c_enum_const() Eric Blake
@ 2015-05-05 12:30 ` Eric Blake
  2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 07/14] qapi: Move camel_to_upper(), c_enum_const() to closely related code Eric Blake
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 25+ messages in thread
From: Eric Blake @ 2015-05-05 12:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, akong, berto, armbru, mdroth

From: Markus Armbruster <armbru@redhat.com>

Missed in commit b0b5819.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
---
 scripts/qapi-types.py |  6 ++----
 scripts/qapi.py       | 11 -----------
 2 files changed, 2 insertions(+), 15 deletions(-)

diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 6ca48c1..9eb08a6 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -180,11 +180,9 @@ const int %(name)s_qtypes[QTYPE_MAX] = {
         assert qtype, "Invalid alternate member"

         ret += mcgen('''
-    [ %(qtype)s ] = %(abbrev)s_KIND_%(enum)s,
+    [ %(qtype)s ] = %(enum_const)s,
 ''',
-        qtype = qtype,
-        abbrev = de_camel_case(name).upper(),
-        enum = c_name(de_camel_case(key),False).upper())
+        qtype = qtype, enum_const = c_enum_const(name + 'Kind', key))

     ret += mcgen('''
 };
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 9209fd5..967dadb 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -729,17 +729,6 @@ def parse_args(typeinfo):
         # value of an optional argument.
         yield (argname, argentry, optional)

-def de_camel_case(name):
-    new_name = ''
-    for ch in name:
-        if ch.isupper() and new_name:
-            new_name += '_'
-        if ch == '-':
-            new_name += '_'
-        else:
-            new_name += ch.lower()
-    return new_name
-
 def camel_case(name):
     new_name = ''
     first = True
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [Qemu-devel] [PATCH v3 07/14] qapi: Move camel_to_upper(), c_enum_const() to closely related code
  2015-05-05 12:30 [Qemu-devel] [PATCH v3 00/14] Fix qapi mangling of downstream names Eric Blake
                   ` (5 preceding siblings ...)
  2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 06/14] qapi: Use c_enum_const() in generate_alternate_qtypes() Eric Blake
@ 2015-05-05 12:30 ` Eric Blake
  2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 08/14] qapi: Make c_type() consistently convert qapi names Eric Blake
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 25+ messages in thread
From: Eric Blake @ 2015-05-05 12:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, akong, berto, armbru, mdroth

From: Markus Armbruster <armbru@redhat.com>

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
---
 scripts/qapi.py | 50 +++++++++++++++++++++++++-------------------------
 1 file changed, 25 insertions(+), 25 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 967dadb..b9822c6 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -742,6 +742,31 @@ def camel_case(name):
             new_name += ch.lower()
     return new_name

+# ENUMName -> ENUM_NAME, EnumName1 -> ENUM_NAME1
+# ENUM_NAME -> ENUM_NAME, ENUM_NAME1 -> ENUM_NAME1, ENUM_Name2 -> ENUM_NAME2
+# ENUM24_Name -> ENUM24_NAME
+def camel_to_upper(value):
+    c_fun_str = c_name(value, False)
+    if value.isupper():
+        return c_fun_str
+
+    new_name = ''
+    l = len(c_fun_str)
+    for i in range(l):
+        c = c_fun_str[i]
+        # When c is upper and no "_" appears before, do more checks
+        if c.isupper() and (i > 0) and c_fun_str[i - 1] != "_":
+            # Case 1: next string is lower
+            # Case 2: previous string is digit
+            if (i < (l - 1) and c_fun_str[i + 1].islower()) or \
+            c_fun_str[i - 1].isdigit():
+                new_name += '_'
+        new_name += c
+    return new_name.lstrip('_').upper()
+
+def c_enum_const(type_name, const_name):
+    return camel_to_upper(type_name + '_' + const_name)
+
 c_name_trans = string.maketrans('.-', '__')

 def c_name(name, protect=True):
@@ -926,28 +951,3 @@ def guardend(name):

 ''',
                  name=guardname(name))
-
-# ENUMName -> ENUM_NAME, EnumName1 -> ENUM_NAME1
-# ENUM_NAME -> ENUM_NAME, ENUM_NAME1 -> ENUM_NAME1, ENUM_Name2 -> ENUM_NAME2
-# ENUM24_Name -> ENUM24_NAME
-def camel_to_upper(value):
-    c_fun_str = c_name(value, False)
-    if value.isupper():
-        return c_fun_str
-
-    new_name = ''
-    l = len(c_fun_str)
-    for i in range(l):
-        c = c_fun_str[i]
-        # When c is upper and no "_" appears before, do more checks
-        if c.isupper() and (i > 0) and c_fun_str[i - 1] != "_":
-            # Case 1: next string is lower
-            # Case 2: previous string is digit
-            if (i < (l - 1) and c_fun_str[i + 1].islower()) or \
-            c_fun_str[i - 1].isdigit():
-                new_name += '_'
-        new_name += c
-    return new_name.lstrip('_').upper()
-
-def c_enum_const(type_name, const_name):
-    return camel_to_upper(type_name + '_' + const_name)
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [Qemu-devel] [PATCH v3 08/14] qapi: Make c_type() consistently convert qapi names
  2015-05-05 12:30 [Qemu-devel] [PATCH v3 00/14] Fix qapi mangling of downstream names Eric Blake
                   ` (6 preceding siblings ...)
  2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 07/14] qapi: Move camel_to_upper(), c_enum_const() to closely related code Eric Blake
@ 2015-05-05 12:30 ` Eric Blake
  2015-05-07  7:39   ` Markus Armbruster
  2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 09/14] qapi: Support downstream enums Eric Blake
                   ` (6 subsequent siblings)
  14 siblings, 1 reply; 25+ messages in thread
From: Eric Blake @ 2015-05-05 12:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, akong, berto, armbru, mdroth

Continuing the string of cleanups for supporting downstream names
containing '.', this patch focuses on ensuring c_type() can
handle a downstream name.  This patch alone does not fix the
places where generator output should be calling this function
but was open-coding things instead, but it gets us a step closer.

Note that we generate a List type for our builtins; the code has
to make sure that ['int'] maps to 'intList' (and not 'q_intList'),
and that a member with type 'int' still maps to the C type 'int';
on the other hand, a member with a name of 'int' will still map
to 'q_int' when going through c_name().  This patch had to teach
type_name() to special-case builtins, since it is used by
c_list_type() which in turn feeds c_type().

Signed-off-by: Eric Blake <eblake@redhat.com>
---
 scripts/qapi.py | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index b9822c6..a1dfc85 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -769,6 +769,9 @@ def c_enum_const(type_name, const_name):

 c_name_trans = string.maketrans('.-', '__')

+# This function is used for converting the name portion of 'name':'type'
+# into a valid C name, for use as a struct member or substring of a
+# function name.
 def c_name(name, protect=True):
     # ANSI X3J11/88-090, 3.1.1
     c89_words = set(['auto', 'break', 'case', 'char', 'const', 'continue',
@@ -800,13 +803,18 @@ def c_name(name, protect=True):
         return "q_" + name
     return name.translate(c_name_trans)

+# This function is used for computing the C type of a 'member':['name'] array.
 def c_list_type(name):
-    return '%sList' % name
+    return type_name(name) + 'List'

+# This function is used for converting the type of 'member':'name' into a
+# substring for use in C pointer types or function names.
 def type_name(name):
     if type(name) == list:
         return c_list_type(name[0])
-    return name
+    if name in builtin_types.keys():
+        return name
+    return c_name(name)

 def add_name(name, info, meta, implicit = False):
     global all_names
@@ -864,6 +872,7 @@ def is_enum(name):

 eatspace = '\033EATSPACE.'

+# This function is used for computing the full C type of 'member':'name'.
 # A special suffix is added in c_type() for pointer types, and it's
 # stripped in mcgen(). So please notice this when you check the return
 # value of c_type() outside mcgen().
@@ -888,13 +897,13 @@ def c_type(name, is_param=False):
     elif type(name) == list:
         return '%s *%s' % (c_list_type(name[0]), eatspace)
     elif is_enum(name):
-        return name
+        return c_name(name)
     elif name == None or len(name) == 0:
         return 'void'
     elif name in events:
         return '%sEvent *%s' % (camel_case(name), eatspace)
     else:
-        return '%s *%s' % (name, eatspace)
+        return '%s *%s' % (c_name(name), eatspace)

 def is_c_ptr(name):
     suffix = "*" + eatspace
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [Qemu-devel] [PATCH v3 09/14] qapi: Support downstream enums
  2015-05-05 12:30 [Qemu-devel] [PATCH v3 00/14] Fix qapi mangling of downstream names Eric Blake
                   ` (7 preceding siblings ...)
  2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 08/14] qapi: Make c_type() consistently convert qapi names Eric Blake
@ 2015-05-05 12:30 ` Eric Blake
  2015-05-07  7:47   ` Markus Armbruster
  2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 10/14] qapi: Support downstream structs Eric Blake
                   ` (5 subsequent siblings)
  14 siblings, 1 reply; 25+ messages in thread
From: Eric Blake @ 2015-05-05 12:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, akong, berto, armbru, mdroth

Enhance the testsuite to cover a downstream enum type and enum
string.  Update the generator to mangle the enum name in the
appropriate places.  The code for generating list visitors must
be careful how it mangles names for enum lists differently than
code for builtin type lists.

Signed-off-by: Eric Blake <eblake@redhat.com>
---
 scripts/qapi-types.py                   | 15 ++++++++-------
 scripts/qapi-visit.py                   | 11 ++++++-----
 tests/qapi-schema/qapi-schema-test.json |  3 +++
 tests/qapi-schema/qapi-schema-test.out  |  4 +++-
 4 files changed, 20 insertions(+), 13 deletions(-)

diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 9eb08a6..1593fc6 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -58,7 +58,7 @@ typedef struct %(name)sList
     struct %(name)sList *next;
 } %(name)sList;
 ''',
-                 name=name)
+                 name=c_name(name))

 def generate_struct_fields(members):
     ret = ''
@@ -115,7 +115,7 @@ def generate_enum_lookup(name, values):
     ret = mcgen('''
 const char *%(name)s_lookup[] = {
 ''',
-                         name=name)
+                name=c_name(name))
     i = 0
     for value in values:
         index = c_enum_const(name, value)
@@ -134,6 +134,7 @@ const char *%(name)s_lookup[] = {
     return ret

 def generate_enum(name, values):
+    name = c_name(name)
     lookup_decl = mcgen('''
 extern const char *%(name)s_lookup[];
 ''',
@@ -247,15 +248,15 @@ extern const int %(name)s_qtypes[];

 def generate_type_cleanup_decl(name):
     ret = mcgen('''
-void qapi_free_%(type)s(%(c_type)s obj);
+void qapi_free_%(name)s(%(c_type)s obj);
 ''',
-                c_type=c_type(name),type=name)
+                c_type=c_type(name), name=c_name(name))
     return ret

 def generate_type_cleanup(name):
     ret = mcgen('''

-void qapi_free_%(type)s(%(c_type)s obj)
+void qapi_free_%(name)s(%(c_type)s obj)
 {
     QapiDeallocVisitor *md;
     Visitor *v;
@@ -266,11 +267,11 @@ void qapi_free_%(type)s(%(c_type)s obj)

     md = qapi_dealloc_visitor_new();
     v = qapi_dealloc_get_visitor(md);
-    visit_type_%(type)s(v, &obj, NULL, NULL);
+    visit_type_%(name)s(v, &obj, NULL, NULL);
     qapi_dealloc_visitor_cleanup(md);
 }
 ''',
-                c_type=c_type(name),type=name)
+                c_type=c_type(name), name=c_name(name))
     return ret


diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 0368e62..feb6c0b 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -146,7 +146,8 @@ void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **e
 ''')
     return ret

-def generate_visit_list(name, members):
+def generate_visit_list(name, members, builtin=False):
+    name = c_name(name, not builtin)
     return mcgen('''

 void visit_type_%(name)sList(Visitor *m, %(name)sList **obj, const char *name, Error **errp)
@@ -183,7 +184,7 @@ void visit_type_%(name)s(Visitor *m, %(name)s *obj, const char *name, Error **er
     visit_type_enum(m, (int *)obj, %(name)s_lookup, "%(name)s", name, errp);
 }
 ''',
-                 name=name)
+                 name=c_name(name))

 def generate_visit_alternate(name, members):
     ret = mcgen('''
@@ -364,7 +365,7 @@ def generate_enum_declaration(name, members):
     ret = mcgen('''
 void visit_type_%(name)sList(Visitor *m, %(name)sList **obj, const char *name, Error **errp);
 ''',
-                name=name)
+                name=c_name(name))

     return ret

@@ -373,7 +374,7 @@ def generate_decl_enum(name, members):

 void visit_type_%(name)s(Visitor *m, %(name)s *obj, const char *name, Error **errp);
 ''',
-                name=name)
+                 name=c_name(name))

 try:
     opts, args = getopt.gnu_getopt(sys.argv[1:], "chbp:i:o:",
@@ -490,7 +491,7 @@ fdecl.write(guardend("QAPI_VISIT_BUILTIN_VISITOR_DECL"))
 # over these cases
 if do_builtins:
     for typename in builtin_types.keys():
-        fdef.write(generate_visit_list(typename, None))
+        fdef.write(generate_visit_list(typename, None, builtin=True))

 for expr in exprs:
     if expr.has_key('struct'):
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index 8193dc1..5f9af66 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -107,3 +107,6 @@
   'data': { '*a': 'int', '*b': 'UserDefOne', 'c': 'str' } }
 { 'event': 'EVENT_D',
   'data': { 'a' : 'EventStructOne', 'b' : 'str', '*c': 'str', '*enum3': 'EnumOne' } }
+
+# test that we correctly compile downstream extensions
+{ 'enum': '__org.qemu_x-Enum', 'data': [ '__org.qemu_x-value' ] }
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index 93c4963..40f0f20 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -22,8 +22,10 @@
  OrderedDict([('event', 'EVENT_A')]),
  OrderedDict([('event', 'EVENT_B'), ('data', OrderedDict())]),
  OrderedDict([('event', 'EVENT_C'), ('data', OrderedDict([('*a', 'int'), ('*b', 'UserDefOne'), ('c', 'str')]))]),
- OrderedDict([('event', 'EVENT_D'), ('data', OrderedDict([('a', 'EventStructOne'), ('b', 'str'), ('*c', 'str'), ('*enum3', 'EnumOne')]))])]
+ OrderedDict([('event', 'EVENT_D'), ('data', OrderedDict([('a', 'EventStructOne'), ('b', 'str'), ('*c', 'str'), ('*enum3', 'EnumOne')]))]),
+ OrderedDict([('enum', '__org.qemu_x-Enum'), ('data', ['__org.qemu_x-value'])])]
 [{'enum_name': 'EnumOne', 'enum_values': ['value1', 'value2', 'value3']},
+ {'enum_name': '__org.qemu_x-Enum', 'enum_values': ['__org.qemu_x-value']},
  {'enum_name': 'UserDefAlternateKind', 'enum_values': None},
  {'enum_name': 'UserDefNativeListUnionKind', 'enum_values': None}]
 [OrderedDict([('struct', 'NestedEnumsOne'), ('data', OrderedDict([('enum1', 'EnumOne'), ('*enum2', 'EnumOne'), ('enum3', 'EnumOne'), ('*enum4', 'EnumOne')]))]),
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [Qemu-devel] [PATCH v3 10/14] qapi: Support downstream structs
  2015-05-05 12:30 [Qemu-devel] [PATCH v3 00/14] Fix qapi mangling of downstream names Eric Blake
                   ` (8 preceding siblings ...)
  2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 09/14] qapi: Support downstream enums Eric Blake
@ 2015-05-05 12:30 ` Eric Blake
  2015-05-07  7:48   ` Markus Armbruster
  2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 11/14] qapi: Support downstream simple unions Eric Blake
                   ` (4 subsequent siblings)
  14 siblings, 1 reply; 25+ messages in thread
From: Eric Blake @ 2015-05-05 12:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, akong, berto, armbru, mdroth

Enhance the testsuite to cover downstream structs, including struct
members and base structs.  Update the generator to mangle the
struct names in the appropriate places.

Signed-off-by: Eric Blake <eblake@redhat.com>
---
 scripts/qapi-types.py                   |  4 ++--
 scripts/qapi-visit.py                   | 11 ++++++-----
 tests/qapi-schema/qapi-schema-test.json |  4 ++++
 tests/qapi-schema/qapi-schema-test.out  |  8 ++++++--
 4 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 1593fc6..5118151 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -45,7 +45,7 @@ typedef struct %(name)sList
     struct %(name)sList *next;
 } %(name)sList;
 ''',
-                 name=name)
+                 name=c_name(name))

 def generate_fwd_enum_struct(name, members):
     return mcgen('''
@@ -87,7 +87,7 @@ def generate_struct(expr):
 struct %(name)s
 {
 ''',
-          name=structname)
+          name=c_name(structname))

     if base:
         ret += generate_struct_fields({'base': base})
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index feb6c0b..a7486ec 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -56,7 +56,7 @@ static void visit_type_%(name)s_fields(Visitor *m, %(name)s **obj, Error **errp)
 {
     Error *err = NULL;
 ''',
-                 name=name)
+                 name=c_name(name))
     push_indent()

     if base:
@@ -111,16 +111,16 @@ def generate_visit_struct_body(name, members):
     ret = mcgen('''
     Error *err = NULL;

-    visit_start_struct(m, (void **)obj, "%(name)s", name, sizeof(%(name)s), &err);
+    visit_start_struct(m, (void **)obj, "%(name)s", name, sizeof(%(c_name)s), &err);
     if (!err) {
         if (*obj) {
-            visit_type_%(name)s_fields(m, obj, errp);
+            visit_type_%(c_name)s_fields(m, obj, errp);
         }
         visit_end_struct(m, &err);
     }
     error_propagate(errp, err);
 ''',
-                name=name)
+                name=name, c_name=c_name(name))

     return ret

@@ -137,7 +137,7 @@ def generate_visit_struct(expr):
 void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **errp)
 {
 ''',
-                name=name)
+                 name=c_name(name))

     ret += generate_visit_struct_body(name, members)

@@ -348,6 +348,7 @@ out:
 def generate_declaration(name, members, builtin_type=False):
     ret = ""
     if not builtin_type:
+        name = c_name(name)
         ret += mcgen('''

 void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **errp);
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index 5f9af66..ca9b34c 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -110,3 +110,7 @@

 # test that we correctly compile downstream extensions
 { 'enum': '__org.qemu_x-Enum', 'data': [ '__org.qemu_x-value' ] }
+{ 'struct': '__org.qemu_x-Base',
+  'data': { '__org.qemu_x-member1': '__org.qemu_x-Enum' } }
+{ 'struct': '__org.qemu_x-Struct', 'base': '__org.qemu_x-Base',
+  'data': { '__org.qemu_x-member2': 'str' } }
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index 40f0f20..6ab4f00 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -23,7 +23,9 @@
  OrderedDict([('event', 'EVENT_B'), ('data', OrderedDict())]),
  OrderedDict([('event', 'EVENT_C'), ('data', OrderedDict([('*a', 'int'), ('*b', 'UserDefOne'), ('c', 'str')]))]),
  OrderedDict([('event', 'EVENT_D'), ('data', OrderedDict([('a', 'EventStructOne'), ('b', 'str'), ('*c', 'str'), ('*enum3', 'EnumOne')]))]),
- OrderedDict([('enum', '__org.qemu_x-Enum'), ('data', ['__org.qemu_x-value'])])]
+ OrderedDict([('enum', '__org.qemu_x-Enum'), ('data', ['__org.qemu_x-value'])]),
+ OrderedDict([('struct', '__org.qemu_x-Base'), ('data', OrderedDict([('__org.qemu_x-member1', '__org.qemu_x-Enum')]))]),
+ OrderedDict([('struct', '__org.qemu_x-Struct'), ('base', '__org.qemu_x-Base'), ('data', OrderedDict([('__org.qemu_x-member2', 'str')]))])]
 [{'enum_name': 'EnumOne', 'enum_values': ['value1', 'value2', 'value3']},
  {'enum_name': '__org.qemu_x-Enum', 'enum_values': ['__org.qemu_x-value']},
  {'enum_name': 'UserDefAlternateKind', 'enum_values': None},
@@ -39,4 +41,6 @@
  OrderedDict([('struct', 'UserDefC'), ('data', OrderedDict([('string1', 'str'), ('string2', 'str')]))]),
  OrderedDict([('struct', 'UserDefUnionBase'), ('data', OrderedDict([('string', 'str'), ('enum1', 'EnumOne')]))]),
  OrderedDict([('struct', 'UserDefOptions'), ('data', OrderedDict([('*i64', ['int']), ('*u64', ['uint64']), ('*u16', ['uint16']), ('*i64x', 'int'), ('*u64x', 'uint64')]))]),
- OrderedDict([('struct', 'EventStructOne'), ('data', OrderedDict([('struct1', 'UserDefOne'), ('string', 'str'), ('*enum2', 'EnumOne')]))])]
+ OrderedDict([('struct', 'EventStructOne'), ('data', OrderedDict([('struct1', 'UserDefOne'), ('string', 'str'), ('*enum2', 'EnumOne')]))]),
+ OrderedDict([('struct', '__org.qemu_x-Base'), ('data', OrderedDict([('__org.qemu_x-member1', '__org.qemu_x-Enum')]))]),
+ OrderedDict([('struct', '__org.qemu_x-Struct'), ('base', '__org.qemu_x-Base'), ('data', OrderedDict([('__org.qemu_x-member2', 'str')]))])]
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [Qemu-devel] [PATCH v3 11/14] qapi: Support downstream simple unions
  2015-05-05 12:30 [Qemu-devel] [PATCH v3 00/14] Fix qapi mangling of downstream names Eric Blake
                   ` (9 preceding siblings ...)
  2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 10/14] qapi: Support downstream structs Eric Blake
@ 2015-05-05 12:30 ` Eric Blake
  2015-05-07  7:49   ` Markus Armbruster
  2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 12/14] qapi: Support downstream flat unions Eric Blake
                   ` (3 subsequent siblings)
  14 siblings, 1 reply; 25+ messages in thread
From: Eric Blake @ 2015-05-05 12:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, akong, berto, armbru, mdroth

Enhance the testsuite to cover downstream simple unions, including
when a union branch is a downstream name.  Update the generator to
mangle the union names in the appropriate places.

Signed-off-by: Eric Blake <eblake@redhat.com>
---
 scripts/qapi-types.py                   | 2 +-
 scripts/qapi-visit.py                   | 8 ++++----
 tests/qapi-schema/qapi-schema-test.json | 1 +
 tests/qapi-schema/qapi-schema-test.out  | 6 ++++--
 4 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 5118151..5b0bc5d 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -193,7 +193,7 @@ const int %(name)s_qtypes[QTYPE_MAX] = {

 def generate_union(expr, meta):

-    name = expr[meta]
+    name = c_name(expr[meta])
     typeinfo = expr['data']

     base = expr.get('base')
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index a7486ec..1397707 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -256,9 +256,9 @@ def generate_visit_union(expr):
         disc_type = enum_define['enum_name']
     else:
         # There will always be a discriminator in the C switch code, by default
-        # it is an enum type generated silently as "'%sKind' % (name)"
-        ret = generate_visit_enum('%sKind' % name, members.keys())
-        disc_type = '%sKind' % (name)
+        # it is an enum type generated silently
+        ret = generate_visit_enum(name + 'Kind', members.keys())
+        disc_type = c_name(name) + 'Kind'

     if base:
         assert discriminator
@@ -282,7 +282,7 @@ void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **e
     }
     if (*obj) {
 ''',
-                 name=name)
+                 name=c_name(name))

     if base:
         ret += mcgen('''
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index ca9b34c..6416d85 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -114,3 +114,4 @@
   'data': { '__org.qemu_x-member1': '__org.qemu_x-Enum' } }
 { 'struct': '__org.qemu_x-Struct', 'base': '__org.qemu_x-Base',
   'data': { '__org.qemu_x-member2': 'str' } }
+{ 'union': '__org.qemu_x-Union1', 'data': { '__org.qemu_x-branch': 'str' } }
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index 6ab4f00..f9ebe08 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -25,11 +25,13 @@
  OrderedDict([('event', 'EVENT_D'), ('data', OrderedDict([('a', 'EventStructOne'), ('b', 'str'), ('*c', 'str'), ('*enum3', 'EnumOne')]))]),
  OrderedDict([('enum', '__org.qemu_x-Enum'), ('data', ['__org.qemu_x-value'])]),
  OrderedDict([('struct', '__org.qemu_x-Base'), ('data', OrderedDict([('__org.qemu_x-member1', '__org.qemu_x-Enum')]))]),
- OrderedDict([('struct', '__org.qemu_x-Struct'), ('base', '__org.qemu_x-Base'), ('data', OrderedDict([('__org.qemu_x-member2', 'str')]))])]
+ OrderedDict([('struct', '__org.qemu_x-Struct'), ('base', '__org.qemu_x-Base'), ('data', OrderedDict([('__org.qemu_x-member2', 'str')]))]),
+ OrderedDict([('union', '__org.qemu_x-Union1'), ('data', OrderedDict([('__org.qemu_x-branch', 'str')]))])]
 [{'enum_name': 'EnumOne', 'enum_values': ['value1', 'value2', 'value3']},
  {'enum_name': '__org.qemu_x-Enum', 'enum_values': ['__org.qemu_x-value']},
  {'enum_name': 'UserDefAlternateKind', 'enum_values': None},
- {'enum_name': 'UserDefNativeListUnionKind', 'enum_values': None}]
+ {'enum_name': 'UserDefNativeListUnionKind', 'enum_values': None},
+ {'enum_name': '__org.qemu_x-Union1Kind', 'enum_values': None}]
 [OrderedDict([('struct', 'NestedEnumsOne'), ('data', OrderedDict([('enum1', 'EnumOne'), ('*enum2', 'EnumOne'), ('enum3', 'EnumOne'), ('*enum4', 'EnumOne')]))]),
  OrderedDict([('struct', 'UserDefZero'), ('data', OrderedDict([('integer', 'int')]))]),
  OrderedDict([('struct', 'UserDefOne'), ('base', 'UserDefZero'), ('data', OrderedDict([('string', 'str'), ('*enum1', 'EnumOne')]))]),
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [Qemu-devel] [PATCH v3 12/14] qapi: Support downstream flat unions
  2015-05-05 12:30 [Qemu-devel] [PATCH v3 00/14] Fix qapi mangling of downstream names Eric Blake
                   ` (10 preceding siblings ...)
  2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 11/14] qapi: Support downstream simple unions Eric Blake
@ 2015-05-05 12:30 ` Eric Blake
  2015-05-07  7:49   ` Markus Armbruster
  2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 13/14] qapi: Support downstream alternates Eric Blake
                   ` (2 subsequent siblings)
  14 siblings, 1 reply; 25+ messages in thread
From: Eric Blake @ 2015-05-05 12:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, akong, berto, armbru, mdroth

Enhance the testsuite to cover downstream flat unions, including
the base type, discriminator name and type, and branch name and
type.  Update the generator to mangle the union names in the
appropriate places.

Signed-off-by: Eric Blake <eblake@redhat.com>
---
 scripts/qapi-types.py                   | 2 +-
 scripts/qapi-visit.py                   | 4 ++--
 tests/qapi-schema/qapi-schema-test.json | 5 +++++
 tests/qapi-schema/qapi-schema-test.out  | 7 +++++--
 4 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 5b0bc5d..13e4b53 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -213,7 +213,7 @@ struct %(name)s
         void *data;
 ''',
                 name=name,
-                discriminator_type_name=discriminator_type_name)
+                discriminator_type_name=c_name(discriminator_type_name))

     for key in typeinfo:
         ret += mcgen('''
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 1397707..def0c50 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -253,7 +253,7 @@ def generate_visit_union(expr):
     if enum_define:
         # Use the enum type as discriminator
         ret = ""
-        disc_type = enum_define['enum_name']
+        disc_type = c_name(enum_define['enum_name'])
     else:
         # There will always be a discriminator in the C switch code, by default
         # it is an enum type generated silently
@@ -291,7 +291,7 @@ void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **e
             goto out_obj;
         }
 ''',
-            name=name)
+                     name=c_name(name))

     if not discriminator:
         disc_key = "type"
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index 6416d85..ac236e3 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -115,3 +115,8 @@
 { 'struct': '__org.qemu_x-Struct', 'base': '__org.qemu_x-Base',
   'data': { '__org.qemu_x-member2': 'str' } }
 { 'union': '__org.qemu_x-Union1', 'data': { '__org.qemu_x-branch': 'str' } }
+{ 'struct': '__org.qemu_x-Struct2',
+  'data': { 'array': ['__org.qemu_x-Union1'] } }
+{ 'union': '__org.qemu_x-Union2', 'base': '__org.qemu_x-Base',
+  'discriminator': '__org.qemu_x-member1',
+  'data': { '__org.qemu_x-value': '__org.qemu_x-Struct2' } }
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index f9ebe08..3fc24e8 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -26,7 +26,9 @@
  OrderedDict([('enum', '__org.qemu_x-Enum'), ('data', ['__org.qemu_x-value'])]),
  OrderedDict([('struct', '__org.qemu_x-Base'), ('data', OrderedDict([('__org.qemu_x-member1', '__org.qemu_x-Enum')]))]),
  OrderedDict([('struct', '__org.qemu_x-Struct'), ('base', '__org.qemu_x-Base'), ('data', OrderedDict([('__org.qemu_x-member2', 'str')]))]),
- OrderedDict([('union', '__org.qemu_x-Union1'), ('data', OrderedDict([('__org.qemu_x-branch', 'str')]))])]
+ OrderedDict([('union', '__org.qemu_x-Union1'), ('data', OrderedDict([('__org.qemu_x-branch', 'str')]))]),
+ OrderedDict([('struct', '__org.qemu_x-Struct2'), ('data', OrderedDict([('array', ['__org.qemu_x-Union1'])]))]),
+ OrderedDict([('union', '__org.qemu_x-Union2'), ('base', '__org.qemu_x-Base'), ('discriminator', '__org.qemu_x-member1'), ('data', OrderedDict([('__org.qemu_x-value', '__org.qemu_x-Struct2')]))])]
 [{'enum_name': 'EnumOne', 'enum_values': ['value1', 'value2', 'value3']},
  {'enum_name': '__org.qemu_x-Enum', 'enum_values': ['__org.qemu_x-value']},
  {'enum_name': 'UserDefAlternateKind', 'enum_values': None},
@@ -45,4 +47,5 @@
  OrderedDict([('struct', 'UserDefOptions'), ('data', OrderedDict([('*i64', ['int']), ('*u64', ['uint64']), ('*u16', ['uint16']), ('*i64x', 'int'), ('*u64x', 'uint64')]))]),
  OrderedDict([('struct', 'EventStructOne'), ('data', OrderedDict([('struct1', 'UserDefOne'), ('string', 'str'), ('*enum2', 'EnumOne')]))]),
  OrderedDict([('struct', '__org.qemu_x-Base'), ('data', OrderedDict([('__org.qemu_x-member1', '__org.qemu_x-Enum')]))]),
- OrderedDict([('struct', '__org.qemu_x-Struct'), ('base', '__org.qemu_x-Base'), ('data', OrderedDict([('__org.qemu_x-member2', 'str')]))])]
+ OrderedDict([('struct', '__org.qemu_x-Struct'), ('base', '__org.qemu_x-Base'), ('data', OrderedDict([('__org.qemu_x-member2', 'str')]))]),
+ OrderedDict([('struct', '__org.qemu_x-Struct2'), ('data', OrderedDict([('array', ['__org.qemu_x-Union1'])]))])]
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [Qemu-devel] [PATCH v3 13/14] qapi: Support downstream alternates
  2015-05-05 12:30 [Qemu-devel] [PATCH v3 00/14] Fix qapi mangling of downstream names Eric Blake
                   ` (11 preceding siblings ...)
  2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 12/14] qapi: Support downstream flat unions Eric Blake
@ 2015-05-05 12:30 ` Eric Blake
  2015-05-07  7:50   ` Markus Armbruster
  2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 14/14] qapi: Support downstream events and commands Eric Blake
  2015-05-12 15:37 ` [Qemu-devel] [PATCH v3 00/14] Fix qapi mangling of downstream names Markus Armbruster
  14 siblings, 1 reply; 25+ messages in thread
From: Eric Blake @ 2015-05-05 12:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, akong, berto, armbru, mdroth

Enhance the testsuite to cover downstream alternates, including
whether the branch name or type is downstream.  Update the
generator to mangle alternate names in the appropriate places.

Signed-off-by: Eric Blake <eblake@redhat.com>
---
 scripts/qapi-types.py                   | 7 ++++---
 scripts/qapi-visit.py                   | 6 +++---
 tests/qapi-schema/qapi-schema-test.json | 2 ++
 tests/qapi-schema/qapi-schema-test.out  | 6 ++++--
 4 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 13e4b53..5665145 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -174,16 +174,17 @@ def generate_alternate_qtypes(expr):
     ret = mcgen('''
 const int %(name)s_qtypes[QTYPE_MAX] = {
 ''',
-    name=name)
+                name=c_name(name))

     for key in members:
         qtype = find_alternate_member_qtype(members[key])
         assert qtype, "Invalid alternate member"

         ret += mcgen('''
-    [ %(qtype)s ] = %(enum_const)s,
+    [%(qtype)s] = %(enum_const)s,
 ''',
-        qtype = qtype, enum_const = c_enum_const(name + 'Kind', key))
+                     qtype = qtype,
+                     enum_const = c_enum_const(name + 'Kind', key))

     ret += mcgen('''
 };
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index def0c50..a16cc54 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -203,11 +203,11 @@ void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **e
     }
     switch ((*obj)->kind) {
 ''',
-    name=name)
+                name=c_name(name))

     # For alternate, always use the default enum type automatically generated
-    # as "'%sKind' % (name)"
-    disc_type = '%sKind' % (name)
+    # as name + 'Kind'
+    disc_type = c_name(name) + 'Kind'

     for key in members:
         assert (members[key] in builtin_types.keys()
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index ac236e3..d586b56 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -120,3 +120,5 @@
 { 'union': '__org.qemu_x-Union2', 'base': '__org.qemu_x-Base',
   'discriminator': '__org.qemu_x-member1',
   'data': { '__org.qemu_x-value': '__org.qemu_x-Struct2' } }
+{ 'alternate': '__org.qemu_x-Alt',
+  'data': { '__org.qemu_x-branch': 'str', 'b': '__org.qemu_x-Base' } }
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index 3fc24e8..2161a90 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -28,12 +28,14 @@
  OrderedDict([('struct', '__org.qemu_x-Struct'), ('base', '__org.qemu_x-Base'), ('data', OrderedDict([('__org.qemu_x-member2', 'str')]))]),
  OrderedDict([('union', '__org.qemu_x-Union1'), ('data', OrderedDict([('__org.qemu_x-branch', 'str')]))]),
  OrderedDict([('struct', '__org.qemu_x-Struct2'), ('data', OrderedDict([('array', ['__org.qemu_x-Union1'])]))]),
- OrderedDict([('union', '__org.qemu_x-Union2'), ('base', '__org.qemu_x-Base'), ('discriminator', '__org.qemu_x-member1'), ('data', OrderedDict([('__org.qemu_x-value', '__org.qemu_x-Struct2')]))])]
+ OrderedDict([('union', '__org.qemu_x-Union2'), ('base', '__org.qemu_x-Base'), ('discriminator', '__org.qemu_x-member1'), ('data', OrderedDict([('__org.qemu_x-value', '__org.qemu_x-Struct2')]))]),
+ OrderedDict([('alternate', '__org.qemu_x-Alt'), ('data', OrderedDict([('__org.qemu_x-branch', 'str'), ('b', '__org.qemu_x-Base')]))])]
 [{'enum_name': 'EnumOne', 'enum_values': ['value1', 'value2', 'value3']},
  {'enum_name': '__org.qemu_x-Enum', 'enum_values': ['__org.qemu_x-value']},
  {'enum_name': 'UserDefAlternateKind', 'enum_values': None},
  {'enum_name': 'UserDefNativeListUnionKind', 'enum_values': None},
- {'enum_name': '__org.qemu_x-Union1Kind', 'enum_values': None}]
+ {'enum_name': '__org.qemu_x-Union1Kind', 'enum_values': None},
+ {'enum_name': '__org.qemu_x-AltKind', 'enum_values': None}]
 [OrderedDict([('struct', 'NestedEnumsOne'), ('data', OrderedDict([('enum1', 'EnumOne'), ('*enum2', 'EnumOne'), ('enum3', 'EnumOne'), ('*enum4', 'EnumOne')]))]),
  OrderedDict([('struct', 'UserDefZero'), ('data', OrderedDict([('integer', 'int')]))]),
  OrderedDict([('struct', 'UserDefOne'), ('base', 'UserDefZero'), ('data', OrderedDict([('string', 'str'), ('*enum1', 'EnumOne')]))]),
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [Qemu-devel] [PATCH v3 14/14] qapi: Support downstream events and commands
  2015-05-05 12:30 [Qemu-devel] [PATCH v3 00/14] Fix qapi mangling of downstream names Eric Blake
                   ` (12 preceding siblings ...)
  2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 13/14] qapi: Support downstream alternates Eric Blake
@ 2015-05-05 12:30 ` Eric Blake
  2015-05-07  7:53   ` Markus Armbruster
  2015-05-12 15:37 ` [Qemu-devel] [PATCH v3 00/14] Fix qapi mangling of downstream names Markus Armbruster
  14 siblings, 1 reply; 25+ messages in thread
From: Eric Blake @ 2015-05-05 12:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, akong, berto, armbru, mdroth

Enhance the testsuite to cover downstream events and commands.
Events worked without more tweaks, but commands needed a few final
updates in the generator to mangle names in the appropriate places.
In making those tweaks, it was easier to drop type_visitor() and
inline its actions instead.

Signed-off-by: Eric Blake <eblake@redhat.com>
---
 scripts/qapi-commands.py                | 16 +++++-----------
 tests/qapi-schema/qapi-schema-test.json |  5 +++++
 tests/qapi-schema/qapi-schema-test.out  |  4 +++-
 tests/test-qmp-commands.c               | 15 +++++++++++++++
 4 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index 8c125ca..0a1d636 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -20,12 +20,6 @@ import os
 import getopt
 import errno

-def type_visitor(name):
-    if type(name) == list:
-        return 'visit_type_%sList' % name[0]
-    else:
-        return 'visit_type_%s' % name
-
 def generate_command_decl(name, args, ret_type):
     arglist=""
     for argname, argtype, optional in parse_args(args):
@@ -153,10 +147,10 @@ if (has_%(c_name)s) {
                          c_name=c_name(argname))
             push_indent()
         ret += mcgen('''
-%(visitor)s(v, &%(c_name)s, "%(name)s", %(errp)s);
+visit_type_%(visitor)s(v, &%(c_name)s, "%(name)s", %(errp)s);
 ''',
                      c_name=c_name(argname), name=argname, argtype=argtype,
-                     visitor=type_visitor(argtype), errp=errparg)
+                     visitor=type_name(argtype), errp=errparg)
         ret += gen_err_check(errarg)
         if optional:
             pop_indent()
@@ -184,7 +178,7 @@ static void qmp_marshal_output_%(c_name)s(%(c_ret_type)s ret_in, QObject **ret_o
     Visitor *v;

     v = qmp_output_get_visitor(mo);
-    %(visitor)s(v, &ret_in, "unused", &local_err);
+    visit_type_%(visitor)s(v, &ret_in, "unused", &local_err);
     if (local_err) {
         goto out;
     }
@@ -195,12 +189,12 @@ out:
     qmp_output_visitor_cleanup(mo);
     md = qapi_dealloc_visitor_new();
     v = qapi_dealloc_get_visitor(md);
-    %(visitor)s(v, &ret_in, "unused", NULL);
+    visit_type_%(visitor)s(v, &ret_in, "unused", NULL);
     qapi_dealloc_visitor_cleanup(md);
 }
 ''',
                 c_ret_type=c_type(ret_type), c_name=c_name(name),
-                visitor=type_visitor(ret_type))
+                visitor=type_name(ret_type))

     return ret

diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index d586b56..c7eaa86 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -122,3 +122,8 @@
   'data': { '__org.qemu_x-value': '__org.qemu_x-Struct2' } }
 { 'alternate': '__org.qemu_x-Alt',
   'data': { '__org.qemu_x-branch': 'str', 'b': '__org.qemu_x-Base' } }
+{ 'event': '__ORG.QEMU_X-EVENT', 'data': '__org.qemu_x-Struct' }
+{ 'command': '__org.qemu_x-command',
+  'data': { 'a': ['__org.qemu_x-Enum'], 'b': ['__org.qemu_x-Struct'],
+            'c': '__org.qemu_x-Union2', 'd': '__org.qemu_x-Alt' },
+  'returns': '__org.qemu_x-Union1' }
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index 2161a90..cf0ccc4 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -29,7 +29,9 @@
  OrderedDict([('union', '__org.qemu_x-Union1'), ('data', OrderedDict([('__org.qemu_x-branch', 'str')]))]),
  OrderedDict([('struct', '__org.qemu_x-Struct2'), ('data', OrderedDict([('array', ['__org.qemu_x-Union1'])]))]),
  OrderedDict([('union', '__org.qemu_x-Union2'), ('base', '__org.qemu_x-Base'), ('discriminator', '__org.qemu_x-member1'), ('data', OrderedDict([('__org.qemu_x-value', '__org.qemu_x-Struct2')]))]),
- OrderedDict([('alternate', '__org.qemu_x-Alt'), ('data', OrderedDict([('__org.qemu_x-branch', 'str'), ('b', '__org.qemu_x-Base')]))])]
+ OrderedDict([('alternate', '__org.qemu_x-Alt'), ('data', OrderedDict([('__org.qemu_x-branch', 'str'), ('b', '__org.qemu_x-Base')]))]),
+ OrderedDict([('event', '__ORG.QEMU_X-EVENT'), ('data', '__org.qemu_x-Struct')]),
+ OrderedDict([('command', '__org.qemu_x-command'), ('data', OrderedDict([('a', ['__org.qemu_x-Enum']), ('b', ['__org.qemu_x-Struct']), ('c', '__org.qemu_x-Union2'), ('d', '__org.qemu_x-Alt')])), ('returns', '__org.qemu_x-Union1')])]
 [{'enum_name': 'EnumOne', 'enum_values': ['value1', 'value2', 'value3']},
  {'enum_name': '__org.qemu_x-Enum', 'enum_values': ['__org.qemu_x-value']},
  {'enum_name': 'UserDefAlternateKind', 'enum_values': None},
diff --git a/tests/test-qmp-commands.c b/tests/test-qmp-commands.c
index ad2e403..9918f23 100644
--- a/tests/test-qmp-commands.c
+++ b/tests/test-qmp-commands.c
@@ -51,6 +51,21 @@ int64_t qmp_user_def_cmd3(int64_t a, bool has_b, int64_t b, Error **errp)
     return a + (has_b ? b : 0);
 }

+__org_qemu_x_Union1 *qmp___org_qemu_x_command(__org_qemu_x_EnumList *a,
+                                              __org_qemu_x_StructList *b,
+                                              __org_qemu_x_Union2 *c,
+                                              __org_qemu_x_Alt *d,
+                                              Error **errp)
+{
+    __org_qemu_x_Union1 *ret = g_new0(__org_qemu_x_Union1, 1);
+
+    ret->kind = ORG_QEMU_X_UNION1_KIND___ORG_QEMU_X_BRANCH;
+    ret->__org_qemu_x_branch = strdup("blah1");
+
+    return ret;
+}
+
+
 /* test commands with no input and no return value */
 static void test_dispatch_cmd(void)
 {
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* Re: [Qemu-devel] [PATCH v3 02/14] qapi: Rename identical c_fun()/c_var() into c_name()
  2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 02/14] qapi: Rename identical c_fun()/c_var() into c_name() Eric Blake
@ 2015-05-07  7:39   ` Markus Armbruster
  0 siblings, 0 replies; 25+ messages in thread
From: Markus Armbruster @ 2015-05-07  7:39 UTC (permalink / raw)
  To: Eric Blake; +Cc: kwolf, akong, berto, qemu-devel, mdroth

Eric Blake <eblake@redhat.com> writes:

> Now that the two functions are identical, we only need one of them,
> and we might as well give it a more descriptive name.  Basically,
> the function serves as the translation from a QAPI name into a
> (portion of a) C identifier, without regards to whether it is a
> variable or function name.
>
> Signed-off-by: Eric Blake <eblake@redhat.com>

Reviewed-by: Markus Armbruster <armbru@redhat.com>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [Qemu-devel] [PATCH v3 08/14] qapi: Make c_type() consistently convert qapi names
  2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 08/14] qapi: Make c_type() consistently convert qapi names Eric Blake
@ 2015-05-07  7:39   ` Markus Armbruster
  2015-05-14  3:38     ` Eric Blake
  0 siblings, 1 reply; 25+ messages in thread
From: Markus Armbruster @ 2015-05-07  7:39 UTC (permalink / raw)
  To: Eric Blake; +Cc: kwolf, akong, berto, qemu-devel, mdroth

Eric Blake <eblake@redhat.com> writes:

> Continuing the string of cleanups for supporting downstream names
> containing '.', this patch focuses on ensuring c_type() can
> handle a downstream name.  This patch alone does not fix the
> places where generator output should be calling this function
> but was open-coding things instead, but it gets us a step closer.
>
> Note that we generate a List type for our builtins; the code has
> to make sure that ['int'] maps to 'intList' (and not 'q_intList'),
> and that a member with type 'int' still maps to the C type 'int';
> on the other hand, a member with a name of 'int' will still map
> to 'q_int' when going through c_name().  This patch had to teach

has to teach

> type_name() to special-case builtins, since it is used by
> c_list_type() which in turn feeds c_type().
>
> Signed-off-by: Eric Blake <eblake@redhat.com>
> ---
>  scripts/qapi.py | 17 +++++++++++++----
>  1 file changed, 13 insertions(+), 4 deletions(-)
>
> diff --git a/scripts/qapi.py b/scripts/qapi.py
> index b9822c6..a1dfc85 100644
> --- a/scripts/qapi.py
> +++ b/scripts/qapi.py
> @@ -769,6 +769,9 @@ def c_enum_const(type_name, const_name):
>
>  c_name_trans = string.maketrans('.-', '__')
>
> +# This function is used for converting the name portion of 'name':'type'
> +# into a valid C name, for use as a struct member or substring of a
> +# function name.

Do we use it only for "the name portion of 'name':'type'"?

I'd prefer a more conventional function comment, like

# Map @name to a valid C identifier.
# If @protect, avoid returning certain ticklish identifiers like C
# keywords by prepending "q_".
# <Explanation of intended use goes here>

>  def c_name(name, protect=True):
>      # ANSI X3J11/88-090, 3.1.1
>      c89_words = set(['auto', 'break', 'case', 'char', 'const', 'continue',
> @@ -800,13 +803,18 @@ def c_name(name, protect=True):
>          return "q_" + name
>      return name.translate(c_name_trans)
>
> +# This function is used for computing the C type of a 'member':['name'] array.

Likewise:

# Map type @name to the C typedef name for the list of this type.

>  def c_list_type(name):
> -    return '%sList' % name
> +    return type_name(name) + 'List'
>
> +# This function is used for converting the type of 'member':'name' into a
> +# substring for use in C pointer types or function names.

Likewise:

# Map type @name to its C typedef name.
# <Explanation of intended use goes here>

Consider rename parameter @name, because it can either be a name string,
or a list containing a name string.  Same for the other functions.
Perhaps in a separate patch for easier review.

>  def type_name(name):
>      if type(name) == list:
>          return c_list_type(name[0])
> -    return name
> +    if name in builtin_types.keys():
> +        return name
> +    return c_name(name)

Together with the change to c_list_type(), this changes type_name() as
follows:

* Name FOO becomes c_name(FOO) instead of FOO, except when FOO is the
  name of a built-in type.  Bug fix when FOO contains '.' or '-' or is
  a ticklish identifier other than a built-in type.

* List of FOO becomes c_name(FOO) + "List" instead of FOOList.  Bug fix
  when FOO contains '.' or '-'.  Not a bug fix when ticklish FOO becomes
  q_FOO, but improves consistency with the element type's C name then.

Correct?

>
>  def add_name(name, info, meta, implicit = False):
>      global all_names
> @@ -864,6 +872,7 @@ def is_enum(name):
>
>  eatspace = '\033EATSPACE.'
>
> +# This function is used for computing the full C type of 'member':'name'.
>  # A special suffix is added in c_type() for pointer types, and it's
>  # stripped in mcgen(). So please notice this when you check the return
>  # value of c_type() outside mcgen().

Likewise:

# Map type @name to its C type expression.
# If @is_param, const-qualify the string type.
# <Explanation of intended use goes here>
# A special suffix...

> @@ -888,13 +897,13 @@ def c_type(name, is_param=False):
>      elif type(name) == list:
>          return '%s *%s' % (c_list_type(name[0]), eatspace)
>      elif is_enum(name):
> -        return name
> +        return c_name(name)
>      elif name == None or len(name) == 0:
>          return 'void'

Aside: len(name) == 0 is a lame way to test name == "".
Aside^2: I wonder whether we ever pass that.

>      elif name in events:
>          return '%sEvent *%s' % (camel_case(name), eatspace)
>      else:
> -        return '%s *%s' % (name, eatspace)
> +        return '%s *%s' % (c_name(name), eatspace)

I figure the else is for complex types.  If that's correct, we should
perhaps add a comment.

>
>  def is_c_ptr(name):
>      suffix = "*" + eatspace

Together with the change to c_list_type(), this changes c_type() as
follows:

* Enum FOO becomes c_name(FOO) instead of FOO.  Bug fix when FOO
  contains '.' or '-' or is a ticklish identifier.

* Complex type FOO becomes c_name(FOO) + "*" instead of FOO *.  Bug fix
  when FOO contains '.' or '-' or is a ticklish identifier.

* List of FOO becomes c_name(FOO) + "List *" instead of FOOList *.  Bug
  fix when FOO contains '.' or '-'.  Not a bug fix when ticklish FOO
  becomes q_FOO, but improves consistency with the element type's C name
  then.

Correct?

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [Qemu-devel] [PATCH v3 09/14] qapi: Support downstream enums
  2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 09/14] qapi: Support downstream enums Eric Blake
@ 2015-05-07  7:47   ` Markus Armbruster
  0 siblings, 0 replies; 25+ messages in thread
From: Markus Armbruster @ 2015-05-07  7:47 UTC (permalink / raw)
  To: Eric Blake; +Cc: kwolf, akong, berto, qemu-devel, mdroth

Eric Blake <eblake@redhat.com> writes:

> Enhance the testsuite to cover a downstream enum type and enum
> string.  Update the generator to mangle the enum name in the
> appropriate places.  The code for generating list visitors must
> be careful how it mangles names for enum lists differently than
> code for builtin type lists.
>
> Signed-off-by: Eric Blake <eblake@redhat.com>

One-liner test addition uncovers about a dozen bugs.

Reviewed-by: Markus Armbruster <armbru@redhat.com>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [Qemu-devel] [PATCH v3 10/14] qapi: Support downstream structs
  2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 10/14] qapi: Support downstream structs Eric Blake
@ 2015-05-07  7:48   ` Markus Armbruster
  0 siblings, 0 replies; 25+ messages in thread
From: Markus Armbruster @ 2015-05-07  7:48 UTC (permalink / raw)
  To: Eric Blake; +Cc: kwolf, akong, berto, qemu-devel, mdroth

Eric Blake <eblake@redhat.com> writes:

> Enhance the testsuite to cover downstream structs, including struct
> members and base structs.  Update the generator to mangle the
> struct names in the appropriate places.
>
> Signed-off-by: Eric Blake <eblake@redhat.com>

Reviewed-by: Markus Armbruster <armbru@redhat.com>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [Qemu-devel] [PATCH v3 11/14] qapi: Support downstream simple unions
  2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 11/14] qapi: Support downstream simple unions Eric Blake
@ 2015-05-07  7:49   ` Markus Armbruster
  0 siblings, 0 replies; 25+ messages in thread
From: Markus Armbruster @ 2015-05-07  7:49 UTC (permalink / raw)
  To: Eric Blake; +Cc: kwolf, akong, berto, qemu-devel, mdroth

Eric Blake <eblake@redhat.com> writes:

> Enhance the testsuite to cover downstream simple unions, including
> when a union branch is a downstream name.  Update the generator to
> mangle the union names in the appropriate places.
>
> Signed-off-by: Eric Blake <eblake@redhat.com>

Reviewed-by: Markus Armbruster <armbru@redhat.com>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [Qemu-devel] [PATCH v3 12/14] qapi: Support downstream flat unions
  2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 12/14] qapi: Support downstream flat unions Eric Blake
@ 2015-05-07  7:49   ` Markus Armbruster
  0 siblings, 0 replies; 25+ messages in thread
From: Markus Armbruster @ 2015-05-07  7:49 UTC (permalink / raw)
  To: Eric Blake; +Cc: kwolf, akong, berto, qemu-devel, mdroth

Eric Blake <eblake@redhat.com> writes:

> Enhance the testsuite to cover downstream flat unions, including
> the base type, discriminator name and type, and branch name and
> type.  Update the generator to mangle the union names in the
> appropriate places.
>
> Signed-off-by: Eric Blake <eblake@redhat.com>

Reviewed-by: Markus Armbruster <armbru@redhat.com>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [Qemu-devel] [PATCH v3 13/14] qapi: Support downstream alternates
  2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 13/14] qapi: Support downstream alternates Eric Blake
@ 2015-05-07  7:50   ` Markus Armbruster
  0 siblings, 0 replies; 25+ messages in thread
From: Markus Armbruster @ 2015-05-07  7:50 UTC (permalink / raw)
  To: Eric Blake; +Cc: kwolf, akong, berto, qemu-devel, mdroth

Eric Blake <eblake@redhat.com> writes:

> Enhance the testsuite to cover downstream alternates, including
> whether the branch name or type is downstream.  Update the
> generator to mangle alternate names in the appropriate places.
>
> Signed-off-by: Eric Blake <eblake@redhat.com>

Reviewed-by: Markus Armbruster <armbru@redhat.com>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [Qemu-devel] [PATCH v3 14/14] qapi: Support downstream events and commands
  2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 14/14] qapi: Support downstream events and commands Eric Blake
@ 2015-05-07  7:53   ` Markus Armbruster
  0 siblings, 0 replies; 25+ messages in thread
From: Markus Armbruster @ 2015-05-07  7:53 UTC (permalink / raw)
  To: Eric Blake; +Cc: kwolf, akong, berto, qemu-devel, mdroth

Eric Blake <eblake@redhat.com> writes:

> Enhance the testsuite to cover downstream events and commands.
> Events worked without more tweaks, but commands needed a few final
> updates in the generator to mangle names in the appropriate places.
> In making those tweaks, it was easier to drop type_visitor() and
> inline its actions instead.
>
> Signed-off-by: Eric Blake <eblake@redhat.com>

Reviewed-by: Markus Armbruster <armbru@redhat.com>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [Qemu-devel] [PATCH v3 00/14] Fix qapi mangling of downstream names
  2015-05-05 12:30 [Qemu-devel] [PATCH v3 00/14] Fix qapi mangling of downstream names Eric Blake
                   ` (13 preceding siblings ...)
  2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 14/14] qapi: Support downstream events and commands Eric Blake
@ 2015-05-12 15:37 ` Markus Armbruster
  14 siblings, 0 replies; 25+ messages in thread
From: Markus Armbruster @ 2015-05-12 15:37 UTC (permalink / raw)
  To: Eric Blake; +Cc: kwolf, akong, berto, qemu-devel, mdroth

Eric Blake <eblake@redhat.com> writes:

> This series makes it possible to use downstream extensions
> (such as __com.redhat_xyz) and temporary names (such as x-foo)
> in every position possible in QAPI schemes, with added tests
> that the generated code still compiles.
>
> There's still some things we could do to the qapi generator,
> such as normalizing struct member names and C manglings and
> creating named implicit types up front on the initial parse
> rather than multiple times in each backend.  But that should
> wait until existing pending patches have landed, to minimize
> rebase churn.
>
> v2 was here:
> https://lists.gnu.org/archive/html/qemu-devel/2015-04/msg01300.html
>
> v3 includes several more of Markus' original RFC series, splits
> up my work into smaller pieces, incorporates fixes suggested by
> Markus, and rebases on top of the pending v8 qapi drop nested
> structs series.  The series has changed enough from v2 that it
> is not worth showing git backport-diff statistics (as only patch
> 1 survived intact).

Applied to my qapi-next branch, thanks!

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [Qemu-devel] [PATCH v3 08/14] qapi: Make c_type() consistently convert qapi names
  2015-05-07  7:39   ` Markus Armbruster
@ 2015-05-14  3:38     ` Eric Blake
  0 siblings, 0 replies; 25+ messages in thread
From: Eric Blake @ 2015-05-14  3:38 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: kwolf, akong, berto, qemu-devel, mdroth

[-- Attachment #1: Type: text/plain, Size: 4421 bytes --]

On 05/07/2015 01:39 AM, Markus Armbruster wrote:
> Eric Blake <eblake@redhat.com> writes:
> 
>> Continuing the string of cleanups for supporting downstream names
>> containing '.', this patch focuses on ensuring c_type() can
>> handle a downstream name.  This patch alone does not fix the
>> places where generator output should be calling this function
>> but was open-coding things instead, but it gets us a step closer.
>>
>> Note that we generate a List type for our builtins; the code has
>> to make sure that ['int'] maps to 'intList' (and not 'q_intList'),
>> and that a member with type 'int' still maps to the C type 'int';
>> on the other hand, a member with a name of 'int' will still map
>> to 'q_int' when going through c_name().  This patch had to teach
> 
> has to teach
> 
>> type_name() to special-case builtins, since it is used by
>> c_list_type() which in turn feeds c_type().
>>

>>
>> +# This function is used for converting the type of 'member':'name' into a
>> +# substring for use in C pointer types or function names.
> 
> Likewise:
> 
> # Map type @name to its C typedef name.
> # <Explanation of intended use goes here>
> 
> Consider rename parameter @name, because it can either be a name string,
> or a list containing a name string.  Same for the other functions.
> Perhaps in a separate patch for easier review.

Sure, will split out a second patch, and post v4 shortly.  c_name() only
operates on strings, but type_name() and c_type() do indeed operate on
more than just strings.

> 
>>  def type_name(name):
>>      if type(name) == list:
>>          return c_list_type(name[0])
>> -    return name
>> +    if name in builtin_types.keys():
>> +        return name
>> +    return c_name(name)
> 
> Together with the change to c_list_type(), this changes type_name() as
> follows:
> 
> * Name FOO becomes c_name(FOO) instead of FOO, except when FOO is the
>   name of a built-in type.  Bug fix when FOO contains '.' or '-' or is
>   a ticklish identifier other than a built-in type.
> 
> * List of FOO becomes c_name(FOO) + "List" instead of FOOList.  Bug fix
>   when FOO contains '.' or '-'.  Not a bug fix when ticklish FOO becomes
>   q_FOO, but improves consistency with the element type's C name then.
> 
> Correct?

Yes. 'unix'->"q_unix" but ['unix']->"unixList" was inconsistent, so it
is now "q_unixList".  But ['int'] must map to "intList" and not
"q_intList", because we have implementations for intList but do not need
generated code for the builtin type int.


> 
> # Map type @name to its C type expression.
> # If @is_param, const-qualify the string type.
> # <Explanation of intended use goes here>
> # A special suffix...
> 
>> @@ -888,13 +897,13 @@ def c_type(name, is_param=False):
>>      elif type(name) == list:
>>          return '%s *%s' % (c_list_type(name[0]), eatspace)
>>      elif is_enum(name):
>> -        return name
>> +        return c_name(name)
>>      elif name == None or len(name) == 0:
>>          return 'void'
> 
> Aside: len(name) == 0 is a lame way to test name == "".
> Aside^2: I wonder whether we ever pass that.

I'll find out :)

> 
>>      elif name in events:
>>          return '%sEvent *%s' % (camel_case(name), eatspace)
>>      else:
>> -        return '%s *%s' % (name, eatspace)
>> +        return '%s *%s' % (c_name(name), eatspace)
> 
> I figure the else is for complex types.  If that's correct, we should
> perhaps add a comment.

Yes, at this point, all that is left is complex types.

> 
>>
>>  def is_c_ptr(name):
>>      suffix = "*" + eatspace
> 
> Together with the change to c_list_type(), this changes c_type() as
> follows:
> 
> * Enum FOO becomes c_name(FOO) instead of FOO.  Bug fix when FOO
>   contains '.' or '-' or is a ticklish identifier.
> 
> * Complex type FOO becomes c_name(FOO) + "*" instead of FOO *.  Bug fix
>   when FOO contains '.' or '-' or is a ticklish identifier.
> 
> * List of FOO becomes c_name(FOO) + "List *" instead of FOOList *.  Bug
>   fix when FOO contains '.' or '-'.  Not a bug fix when ticklish FOO
>   becomes q_FOO, but improves consistency with the element type's C name
>   then.
> 
> Correct?

Yes. I can try and fold that into the commit message.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2015-05-14  3:38 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-05 12:30 [Qemu-devel] [PATCH v3 00/14] Fix qapi mangling of downstream names Eric Blake
2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 01/14] qapi: Fix C identifiers generated for names containing '.' Eric Blake
2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 02/14] qapi: Rename identical c_fun()/c_var() into c_name() Eric Blake
2015-05-07  7:39   ` Markus Armbruster
2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 03/14] qapi: Rename _generate_enum_string() to camel_to_upper() Eric Blake
2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 04/14] qapi: Rename generate_enum_full_value() to c_enum_const() Eric Blake
2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 05/14] qapi: Simplify c_enum_const() Eric Blake
2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 06/14] qapi: Use c_enum_const() in generate_alternate_qtypes() Eric Blake
2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 07/14] qapi: Move camel_to_upper(), c_enum_const() to closely related code Eric Blake
2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 08/14] qapi: Make c_type() consistently convert qapi names Eric Blake
2015-05-07  7:39   ` Markus Armbruster
2015-05-14  3:38     ` Eric Blake
2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 09/14] qapi: Support downstream enums Eric Blake
2015-05-07  7:47   ` Markus Armbruster
2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 10/14] qapi: Support downstream structs Eric Blake
2015-05-07  7:48   ` Markus Armbruster
2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 11/14] qapi: Support downstream simple unions Eric Blake
2015-05-07  7:49   ` Markus Armbruster
2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 12/14] qapi: Support downstream flat unions Eric Blake
2015-05-07  7:49   ` Markus Armbruster
2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 13/14] qapi: Support downstream alternates Eric Blake
2015-05-07  7:50   ` Markus Armbruster
2015-05-05 12:30 ` [Qemu-devel] [PATCH v3 14/14] qapi: Support downstream events and commands Eric Blake
2015-05-07  7:53   ` Markus Armbruster
2015-05-12 15:37 ` [Qemu-devel] [PATCH v3 00/14] Fix qapi mangling of downstream names Markus Armbruster

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.