qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: Michael Roth <mdroth@linux.vnet.ibm.com>
Cc: kwolf@redhat.com, peter.maydell@linaro.org, aliguori@us.ibm.com,
	qemu-devel@nongnu.org, blauwirbel@gmail.com, eblake@redhat.com
Subject: Re: [Qemu-devel] [PATCH v3 05/22] qapi: qapi_visit.py, support arrays and complex qapi definitions
Date: Fri, 05 Oct 2012 10:11:10 +0200	[thread overview]
Message-ID: <506E961E.3090403@redhat.com> (raw)
In-Reply-To: <1349372021-31212-6-git-send-email-mdroth@linux.vnet.ibm.com>

Il 04/10/2012 19:33, Michael Roth ha scritto:
> Add support for arrays in the code generators.
> 
> Complex field descriptions can now be used to provide additional
> information to the visitor generators, such as the max size of an array,
> or the field within a struct to use to determine how many elements are
> present in the array to avoid serializing uninitialized elements.
> 
> Add handling for these in the code generators as well.
> 
> Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
> Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
> ---
>  scripts/qapi.py          |    8 ++++--
>  scripts/qapi_commands.py |    8 +++---
>  scripts/qapi_types.py    |    2 +-
>  scripts/qapi_visit.py    |   64 +++++++++++++++++++++++++++++++++++++++++-----
>  4 files changed, 68 insertions(+), 14 deletions(-)
> 
> diff --git a/scripts/qapi.py b/scripts/qapi.py
> index 122b4cb..a347203 100644
> --- a/scripts/qapi.py
> +++ b/scripts/qapi.py
> @@ -110,12 +110,16 @@ def parse_args(typeinfo):
>          argentry = typeinfo[member]
>          optional = False
>          structured = False
> +        annotated = False
>          if member.startswith('*'):
>              argname = member[1:]
>              optional = True
>          if isinstance(argentry, OrderedDict):
> -            structured = True
> -        yield (argname, argentry, optional, structured)
> +            if argentry.has_key('<annotated>'):
> +                annotated = True
> +            else:
> +                structured = True
> +        yield (argname, argentry, optional, structured, annotated)
>  
>  def de_camel_case(name):
>      new_name = ''
> diff --git a/scripts/qapi_commands.py b/scripts/qapi_commands.py
> index 3c4678d..a2e0c23 100644
> --- a/scripts/qapi_commands.py
> +++ b/scripts/qapi_commands.py
> @@ -32,7 +32,7 @@ void %(visitor)s(Visitor *m, %(name)s * obj, const char *name, Error **errp);
>  
>  def generate_command_decl(name, args, ret_type):
>      arglist=""
> -    for argname, argtype, optional, structured in parse_args(args):
> +    for argname, argtype, optional, structured, annotated in parse_args(args):
>          argtype = c_type(argtype)
>          if argtype == "char *":
>              argtype = "const char *"
> @@ -50,7 +50,7 @@ def gen_sync_call(name, args, ret_type, indent=0):
>      retval=""
>      if ret_type:
>          retval = "retval = "
> -    for argname, argtype, optional, structured in parse_args(args):
> +    for argname, argtype, optional, structured, annotated in parse_args(args):
>          if optional:
>              arglist += "has_%s, " % c_var(argname)
>          arglist += "%s, " % (c_var(argname))
> @@ -106,7 +106,7 @@ Visitor *v;
>  def gen_visitor_input_vars_decl(args):
>      ret = ""
>      push_indent()
> -    for argname, argtype, optional, structured in parse_args(args):
> +    for argname, argtype, optional, structured, annotated in parse_args(args):
>          if optional:
>              ret += mcgen('''
>  bool has_%(argname)s = false;
> @@ -145,7 +145,7 @@ v = qmp_input_get_visitor(mi);
>  ''',
>                       obj=obj)
>  
> -    for argname, argtype, optional, structured in parse_args(args):
> +    for argname, argtype, optional, structured, annotated in parse_args(args):
>          if optional:
>              ret += mcgen('''
>  visit_start_optional(v, &has_%(c_name)s, "%(name)s", errp);
> diff --git a/scripts/qapi_types.py b/scripts/qapi_types.py
> index 49ef569..6518768 100644
> --- a/scripts/qapi_types.py
> +++ b/scripts/qapi_types.py
> @@ -45,7 +45,7 @@ struct %(name)s
>  ''',
>            name=structname)
>  
> -    for argname, argentry, optional, structured in parse_args(members):
> +    for argname, argentry, optional, structured, annotated in parse_args(members):
>          if optional:
>              ret += mcgen('''
>      bool has_%(c_name)s;
> diff --git a/scripts/qapi_visit.py b/scripts/qapi_visit.py
> index 974e458..b3f34a2 100644
> --- a/scripts/qapi_visit.py
> +++ b/scripts/qapi_visit.py
> @@ -16,6 +16,52 @@ import sys
>  import os
>  import getopt
>  import errno
> +import types
> +
> +def generate_visit_carray_body(name, info):
> +    if info['array_size'][0].isdigit():
> +        array_size = info['array_size']
> +    elif info['array_size'][0] == '(' and info['array_size'][-1] == ')':
> +        array_size = info['array_size']
> +    else:
> +        array_size = "(*obj)->%s" % info['array_size']
> +
> +    if info.has_key('array_capacity'):
> +        array_capacity = info['array_capacity']
> +    else:
> +        array_capacity = array_size
> +
> +    if camel_case(de_camel_case(info['type'][0])) == info['type'][0]:

Please add a comment that this is for array of objects vs. array of pointers.

> +        ret = mcgen('''
> +visit_start_carray(m, (void **)obj, "%(name)s", %(array_capacity)s, sizeof(%(type)s), errp);
> +int %(name)s_i;
> +for (%(name)s_i = 0; %(name)s_i < %(array_size)s; %(name)s_i++) {
> +    %(type)s %(name)s_ptr = &(*obj)->%(name)s[%(name)s_i];
> +    visit_next_carray(m, errp);
> +    visit_type_%(type_short)s(m, &%(name)s_ptr, NULL, errp);
> +}
> +visit_end_carray(m, errp);

This may leave unbalanced items on the stack.  See the idiom that is used for
lists.

    if (!error_is_set(errp)) {
        visit_start_list(m, name, &err);
        if (!err) {
            for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) {
                %(name)sList *native_i = (%(name)sList *)i;
                visit_type_%(name)s(m, &native_i->value, NULL, &err);
            }
            error_propagate(errp, err);
            err = NULL;

            /* Always call end_list if start_list succeeded.  */
            visit_end_list(m, &err);
        }
        error_propagate(errp, err);
    }


> +''',
> +                    name=name, type=c_type(info['type'][0]),
> +                    type_short=info['type'][0],
> +                    array_size=array_size,
> +                    array_capacity=array_capacity)
> +    else:
> +        ret = mcgen('''
> +visit_start_carray(m, (void **)obj, "%(name)s", %(array_capacity)s, sizeof(%(type)s), errp);
> +int %(name)s_i;
> +for (%(name)s_i = 0; %(name)s_i < %(array_size)s; %(name)s_i++) {
> +    %(type)s *%(name)s_ptr = (%(type)s *)&(*obj)->%(name)s[%(name)s_i];

Is the cast needed?

> +    visit_next_carray(m, errp);
> +    visit_type_%(type_short)s(m, %(name)s_ptr, NULL, errp);
> +}
> +visit_end_carray(m, errp);
> +''',
> +                    name=name, type=c_type(info['type'][0]),
> +                    type_short=info['type'][0],
> +                    array_size=array_size,
> +                    array_capacity=array_capacity)
> +    return ret
>  
>  def generate_visit_struct_body(field_prefix, name, members):
>      ret = mcgen('''
> @@ -45,10 +91,10 @@ if (!err) {
>  
>      push_indent()
>      push_indent()
> -    for argname, argentry, optional, structured in parse_args(members):
> +    for argname, argentry, optional, structured, annotated in parse_args(members):
>          if optional:
>              ret += mcgen('''
> -visit_start_optional(m, obj ? &(*obj)->%(c_prefix)shas_%(c_name)s : NULL, "%(name)s", &err);
> +visit_start_optional(m, obj ? &(*obj)->%(c_prefix)shas_%(c_name)s : NULL, "%(name)s", errp);
>  if (obj && (*obj)->%(prefix)shas_%(c_name)s) {
>  ''',
>                           c_prefix=c_var(field_prefix), prefix=field_prefix,
> @@ -58,12 +104,16 @@ if (obj && (*obj)->%(prefix)shas_%(c_name)s) {
>          if structured:
>              ret += generate_visit_struct_body(field_prefix + argname, argname, argentry)
>          else:
> -            ret += mcgen('''
> -visit_type_%(type)s(m, obj ? &(*obj)->%(c_prefix)s%(c_name)s : NULL, "%(name)s", &err);
> +            if annotated:
> +                if isinstance(argentry['type'], types.ListType):
> +                    ret += generate_visit_carray_body(argname, argentry)

Please add documentation to docs/qapi-code-gen.txt for this and the other patches.

> +            else:
> +                ret += mcgen('''
> +visit_type_%(type)s(m, obj ? &(*obj)->%(c_prefix)s%(c_name)s : NULL, "%(name)s", errp);
>  ''',
> -                         c_prefix=c_var(field_prefix), prefix=field_prefix,
> -                         type=type_name(argentry), c_name=c_var(argname),
> -                         name=argname)
> +                             c_prefix=c_var(field_prefix), prefix=field_prefix,
> +                             type=type_name(argentry), c_name=c_var(argname),
> +                             name=argname)
>  
>          if optional:
>              pop_indent()
> 

  reply	other threads:[~2012-10-05  8:11 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-10-04 17:33 [Qemu-devel] [PATCH v3] Add infrastructure for QIDL-based device serialization Michael Roth
2012-10-04 17:33 ` [Qemu-devel] [PATCH v3 01/22] qapi: qapi-visit.py -> qapi_visit.py so we can import Michael Roth
2012-10-04 17:33 ` [Qemu-devel] [PATCH v3 02/22] qapi: qapi-types.py -> qapi_types.py Michael Roth
2012-10-04 17:33 ` [Qemu-devel] [PATCH v3 03/22] qapi: qapi-commands.py -> qapi_commands.py Michael Roth
2012-10-04 17:33 ` [Qemu-devel] [PATCH v3 04/22] qapi: qapi_visit.py, make code useable as module Michael Roth
2012-10-04 17:33 ` [Qemu-devel] [PATCH v3 05/22] qapi: qapi_visit.py, support arrays and complex qapi definitions Michael Roth
2012-10-05  8:11   ` Paolo Bonzini [this message]
2012-10-04 17:33 ` [Qemu-devel] [PATCH v3 06/22] qapi: qapi_visit.py, support generating static functions Michael Roth
2012-10-04 17:33 ` [Qemu-devel] [PATCH v3 07/22] qapi: qapi_visit.py, support for visiting non-pointer/embedded structs Michael Roth
2012-10-05  8:09   ` Paolo Bonzini
2012-10-04 17:33 ` [Qemu-devel] [PATCH v3 08/22] qapi: add visitor interfaces for C arrays Michael Roth
2012-10-04 17:33 ` [Qemu-devel] [PATCH v3 09/22] qapi: QmpOutputVisitor, implement array handling Michael Roth
2012-10-05  8:05   ` Paolo Bonzini
2012-10-04 17:33 ` [Qemu-devel] [PATCH v3 10/22] qapi: QmpInputVisitor, " Michael Roth
2012-10-04 17:33 ` [Qemu-devel] [PATCH v3 11/22] qapi: qapi.py, make json parser more robust Michael Roth
2012-10-04 17:33 ` [Qemu-devel] [PATCH v3 12/22] qapi: add open-coded visitor for struct tm types Michael Roth
2012-10-04 17:33 ` [Qemu-devel] [PATCH v3 13/22] qom-fuse: force single-threaded mode to avoid QMP races Michael Roth
2012-10-04 17:33 ` [Qemu-devel] [PATCH v3 14/22] qom-fuse: workaround for truncated properties > 4096 Michael Roth
2012-10-04 17:33 ` [Qemu-devel] [PATCH v3 15/22] module additions for schema registration Michael Roth
2012-10-04 17:33 ` [Qemu-devel] [PATCH v3 16/22] qdev: move Property-related declarations to qdev-properties.h Michael Roth
2012-10-04 17:33 ` [Qemu-devel] [PATCH v3 17/22] qidl: add documentation Michael Roth
2012-10-04 17:33 ` [Qemu-devel] [PATCH v3 18/22] qidl: add lexer library (based on QC parser) Michael Roth
2012-10-04 17:33 ` [Qemu-devel] [PATCH v3 19/22] qidl: add C parser " Michael Roth
2012-10-04 17:33 ` [Qemu-devel] [PATCH v3 20/22] qidl: add QAPI-based code generator Michael Roth
2012-10-04 17:33 ` [Qemu-devel] [PATCH v3 21/22] qidl: qidl.h, definitions for qidl annotations Michael Roth
2012-10-05  8:14   ` Paolo Bonzini
2012-10-05 14:50     ` Michael Roth
2012-10-05 15:07   ` Paolo Bonzini
2012-10-05 15:41     ` Michael Roth
2012-10-05 15:53       ` Paolo Bonzini
2012-10-05 16:47         ` Michael Roth
2012-10-15 13:37           ` Paolo Bonzini
2012-10-15 15:50             ` Michael Roth
2012-10-04 17:33 ` [Qemu-devel] [PATCH v3 22/22] qidl: unit tests and build infrastructure Michael Roth
2012-10-05  8:24   ` Paolo Bonzini
2012-10-12 21:39     ` Michael Roth
2012-10-13  7:12       ` Paolo Bonzini
2012-10-15  8:52       ` Kevin Wolf
2012-10-15 14:48         ` Michael Roth
2012-10-05  8:26 ` [Qemu-devel] [PATCH v3] Add infrastructure for QIDL-based device serialization Paolo Bonzini
2012-10-05 14:52   ` Michael Roth

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=506E961E.3090403@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=aliguori@us.ibm.com \
    --cc=blauwirbel@gmail.com \
    --cc=eblake@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=mdroth@linux.vnet.ibm.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

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

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).