diff mbox

[RFC,07/10] qapi script: support direct inheritance for struct

Message ID 1383611860-9053-8-git-send-email-xiawenc@linux.vnet.ibm.com
State New
Headers show

Commit Message

Wayne Xia Nov. 5, 2013, 12:37 a.m. UTC
Now it is possible to inherit another struct inside data directly,
which saves trouble to define trivial structure.

Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
---
 docs/qapi-code-gen.txt |   21 +++++++++++++++++++++
 scripts/qapi-visit.py  |   14 ++++++++++----
 2 files changed, 31 insertions(+), 4 deletions(-)

Comments

Eric Blake Nov. 5, 2013, 1:41 p.m. UTC | #1
On 11/04/2013 05:37 PM, Wenchao Xia wrote:
> Now it is possible to inherit another struct inside data directly,
> which saves trouble to define trivial structure.
> 
> Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
> ---
>  docs/qapi-code-gen.txt |   21 +++++++++++++++++++++
>  scripts/qapi-visit.py  |   14 ++++++++++----
>  2 files changed, 31 insertions(+), 4 deletions(-)
> 
> diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
> index 0728f36..3e42ff4 100644
> --- a/docs/qapi-code-gen.txt
> +++ b/docs/qapi-code-gen.txt
> @@ -70,6 +70,27 @@ both fields like this:
>   { "file": "/some/place/my-image",
>     "backing": "/some/place/my-backing-file" }
>  
> +It is possible to directly inherit other struct by keyword '_base':
> +
> + { 'type': 'NetworkConnectionInfo', 'data': { 'host': 'str', 'service': 'str' } }
> + { 'type': 'VncConnectionInfo',
> +   'data': {
> +      'server': {
> +          '_base': 'NetworkConnectionInfo',

Interesting idea for shorthand.  However, I would suggest that you pick
a different character than '_', since '_' is valid in names.  That is,
we already have special handling of leading '*' to mark a field as
optional, so I suggest something like '^' to mark a base class.  By
using a non-name character, it becomes more obvious that the leading
character has a special meaning to the qapi generator.

I'm also not convinced yet that we want this shorthand; in particular,
I'm worried whether it will make the introspection patches harder to write.
Wayne Xia Nov. 6, 2013, 3:20 a.m. UTC | #2
于 2013/11/5 21:41, Eric Blake 写道:
> On 11/04/2013 05:37 PM, Wenchao Xia wrote:
>> Now it is possible to inherit another struct inside data directly,
>> which saves trouble to define trivial structure.
>>
>> Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
>> ---
>>   docs/qapi-code-gen.txt |   21 +++++++++++++++++++++
>>   scripts/qapi-visit.py  |   14 ++++++++++----
>>   2 files changed, 31 insertions(+), 4 deletions(-)
>>
>> diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
>> index 0728f36..3e42ff4 100644
>> --- a/docs/qapi-code-gen.txt
>> +++ b/docs/qapi-code-gen.txt
>> @@ -70,6 +70,27 @@ both fields like this:
>>    { "file": "/some/place/my-image",
>>      "backing": "/some/place/my-backing-file" }
>>
>> +It is possible to directly inherit other struct by keyword '_base':
>> +
>> + { 'type': 'NetworkConnectionInfo', 'data': { 'host': 'str', 'service': 'str' } }
>> + { 'type': 'VncConnectionInfo',
>> +   'data': {
>> +      'server': {
>> +          '_base': 'NetworkConnectionInfo',
>
> Interesting idea for shorthand.  However, I would suggest that you pick
> a different character than '_', since '_' is valid in names.  That is,
> we already have special handling of leading '*' to mark a field as
> optional, so I suggest something like '^' to mark a base class.  By
> using a non-name character, it becomes more obvious that the leading
> character has a special meaning to the qapi generator.
>
> I'm also not convinced yet that we want this shorthand; in particular,
> I'm worried whether it will make the introspection patches harder to write.
>
   I am not sure about this approach either, so put RFC tag on it. The
purpose is allow not to define structures that would be only used once.

   What instrospection patch do you mean? Python instrospection
mechnism? You mean there is a python utility which recognize
only keyword "base" now?
Eric Blake Nov. 6, 2013, 1:33 p.m. UTC | #3
On 11/05/2013 08:20 PM, Wenchao Xia wrote:
>>> +      'server': {
>>> +          '_base': 'NetworkConnectionInfo',
>>
>> Interesting idea for shorthand.  However, I would suggest that you pick
>> a different character than '_', since '_' is valid in names.  That is,
>> we already have special handling of leading '*' to mark a field as
>> optional, so I suggest something like '^' to mark a base class.  By
>> using a non-name character, it becomes more obvious that the leading
>> character has a special meaning to the qapi generator.
>>
>> I'm also not convinced yet that we want this shorthand; in particular,
>> I'm worried whether it will make the introspection patches harder to
>> write.
>>
>   I am not sure about this approach either, so put RFC tag on it. The
> purpose is allow not to define structures that would be only used once.
> 
>   What instrospection patch do you mean? Python instrospection
> mechnism? You mean there is a python utility which recognize
> only keyword "base" now?

No, I'm talking about Amos' patches to expose the qapi to the user via a
QMP command.  Last version proposed was here:
https://lists.gnu.org/archive/html/qemu-devel/2013-07/msg02494.html
although with the addition of discriminated union types in the meantime,
my understanding is Amos is planning on posting another version soon for
the 1.8 timeframe.
Wayne Xia Nov. 7, 2013, 2:33 a.m. UTC | #4
于 2013/11/6 21:33, Eric Blake 写道:
> On 11/05/2013 08:20 PM, Wenchao Xia wrote:
>>>> +      'server': {
>>>> +          '_base': 'NetworkConnectionInfo',
>>>
>>> Interesting idea for shorthand.  However, I would suggest that you pick
>>> a different character than '_', since '_' is valid in names.  That is,
>>> we already have special handling of leading '*' to mark a field as
>>> optional, so I suggest something like '^' to mark a base class.  By
>>> using a non-name character, it becomes more obvious that the leading
>>> character has a special meaning to the qapi generator.
>>>
>>> I'm also not convinced yet that we want this shorthand; in particular,
>>> I'm worried whether it will make the introspection patches harder to
>>> write.
>>>
>>    I am not sure about this approach either, so put RFC tag on it. The
>> purpose is allow not to define structures that would be only used once.
>>
>>    What instrospection patch do you mean? Python instrospection
>> mechnism? You mean there is a python utility which recognize
>> only keyword "base" now?
>
> No, I'm talking about Amos' patches to expose the qapi to the user via a
> QMP command.  Last version proposed was here:
> https://lists.gnu.org/archive/html/qemu-devel/2013-07/msg02494.html
> although with the addition of discriminated union types in the meantime,
> my understanding is Amos is planning on posting another version soon for
> the 1.8 timeframe.
>
   I'll drop this patch now.
diff mbox

Patch

diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
index 0728f36..3e42ff4 100644
--- a/docs/qapi-code-gen.txt
+++ b/docs/qapi-code-gen.txt
@@ -70,6 +70,27 @@  both fields like this:
  { "file": "/some/place/my-image",
    "backing": "/some/place/my-backing-file" }
 
+It is possible to directly inherit other struct by keyword '_base':
+
+ { 'type': 'NetworkConnectionInfo', 'data': { 'host': 'str', 'service': 'str' } }
+ { 'type': 'VncConnectionInfo',
+   'data': {
+      'server': {
+          '_base': 'NetworkConnectionInfo',
+          '*auth': 'str' },
+      'client': 'NetworkConnectionInfo'
+      } }
+
+Result on the wire could be:
+
+{
+  "server": { "host": "192.168.1.1",
+              "service": "8080",
+              "auth': "none" },
+  "client": { "host": "192.168.1.2",
+              "service": "1223" }
+}
+
 === Enumeration types ===
 
 An enumeration type is a dictionary containing a single key whose value is a
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 2b13ad0..f0f0942 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -17,7 +17,7 @@  import os
 import getopt
 import errno
 
-def generate_visit_struct_fields(name, field_prefix, fn_prefix, members, base = None):
+def generate_visit_struct_fields(name, field_prefix, fn_prefix, members, base = None, base_name = 'base'):
     substructs = []
     ret = ''
     full_name = name if not fn_prefix else "%s_%s" % (name, fn_prefix)
@@ -30,8 +30,14 @@  def generate_visit_struct_fields(name, field_prefix, fn_prefix, members, base =
                 nested_fn_prefix = "%s_%s" % (fn_prefix, argname)
 
             nested_field_prefix = "%s%s." % (field_prefix, argname)
+
+            _base = argentry.get('_base')
+            if _base:
+                del argentry['_base']
+
             ret += generate_visit_struct_fields(name, nested_field_prefix,
-                                                nested_fn_prefix, argentry)
+                                                nested_fn_prefix, argentry,
+                                                _base, '_base')
 
     ret += mcgen('''
 
@@ -44,7 +50,7 @@  static void visit_type_%(full_name)s_fields(Visitor *m, %(name)s ** obj, Error *
 
     if base:
         ret += mcgen('''
-visit_start_implicit_struct(m, obj ? (void**) &(*obj)->%(c_name)s : NULL, sizeof(%(type)s), &err);
+visit_start_implicit_struct(m, obj ? (void**) &(*obj)->%(c_prefix)s%(c_name)s : NULL, sizeof(%(type)s), &err);
 if (!err) {
     visit_type_%(type)s_fields(m, obj ? &(*obj)->%(c_prefix)s%(c_name)s : NULL, &err);
     error_propagate(errp, err);
@@ -53,7 +59,7 @@  if (!err) {
 }
 ''',
                      c_prefix=c_var(field_prefix),
-                     type=type_name(base), c_name=c_var('base'))
+                     type=type_name(base), c_name=c_var(base_name))
 
     for argname, argentry, optional, structured in parse_args(members):
         if optional: