From: Michael Roth <mdroth@linux.vnet.ibm.com>
To: qemu-devel@nongnu.org
Cc: blauwirbel@gmail.com, aliguori@us.ibm.com
Subject: [Qemu-devel] [PATCH 05/20] qapi: qapi_visit.py, support arrays and complex qapi definitions
Date: Tue, 14 Aug 2012 11:27:11 -0500 [thread overview]
Message-ID: <1344961646-21194-6-git-send-email-mdroth@linux.vnet.ibm.com> (raw)
In-Reply-To: <1344961646-21194-1-git-send-email-mdroth@linux.vnet.ibm.com>
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 cf601ae..8babfe1 100644
--- a/scripts/qapi_types.py
+++ b/scripts/qapi_types.py
@@ -35,7 +35,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 25707f5..aac2172 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]:
+ 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_type_%(type_short)s(m, &%(name)s_ptr, NULL, errp);
+ visit_next_carray(m, 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)
+ 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];
+ 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)
+ 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()
--
1.7.9.5
next prev parent reply other threads:[~2012-08-14 16:28 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-08-14 16:27 [Qemu-devel] Add infrastructure for supporting QIDL annotations Michael Roth
2012-08-14 16:27 ` [Qemu-devel] [PATCH 01/20] qapi: qapi-visit.py -> qapi_visit.py so we can import Michael Roth
2012-08-14 16:27 ` [Qemu-devel] [PATCH 02/20] qapi: qapi-types.py -> qapi_types.py Michael Roth
2012-08-14 16:27 ` [Qemu-devel] [PATCH 03/20] qapi: qapi-commands.py -> qapi_commands.py Michael Roth
2012-08-14 16:27 ` [Qemu-devel] [PATCH 04/20] qapi: qapi_visit.py, make code useable as module Michael Roth
2012-08-14 16:27 ` Michael Roth [this message]
2012-08-14 16:27 ` [Qemu-devel] [PATCH 06/20] qapi: add visitor interfaces for C arrays Michael Roth
2012-08-14 16:27 ` [Qemu-devel] [PATCH 07/20] qapi: qapi_visit.py, support generating static functions Michael Roth
2012-08-14 16:27 ` [Qemu-devel] [PATCH 08/20] qapi: qapi_visit.py, support for visiting non-pointer/embedded structs Michael Roth
2012-08-14 16:27 ` [Qemu-devel] [PATCH 09/20] qapi: QmpOutputVisitor, implement array handling Michael Roth
2012-08-14 16:27 ` [Qemu-devel] [PATCH 10/20] qapi: QmpInputVisitor, " Michael Roth
2012-08-14 16:27 ` [Qemu-devel] [PATCH 11/20] qapi: qapi.py, make json parser more robust Michael Roth
2012-08-14 16:27 ` [Qemu-devel] [PATCH 12/20] qapi: add open-coded visitor for struct tm types Michael Roth
2012-08-14 16:27 ` [Qemu-devel] [PATCH 13/20] qom-fuse: workaround for truncated properties > 4096 Michael Roth
2012-08-14 16:27 ` [Qemu-devel] [PATCH 14/20] module additions for schema registration Michael Roth
2012-08-14 16:27 ` [Qemu-devel] [PATCH 15/20] qdev: move Property-related declarations to qdev-properties.h Michael Roth
2012-08-14 16:27 ` [Qemu-devel] [PATCH 16/20] qidl: Add documentation Michael Roth
2012-08-14 19:01 ` Eric Blake
2012-08-14 19:41 ` Peter Maydell
2012-08-14 22:15 ` Michael Roth
2012-08-14 22:20 ` Peter Maydell
2012-08-18 14:19 ` Blue Swirl
2012-08-14 16:27 ` [Qemu-devel] [PATCH 17/20] qidl: parser, initial import from qc.git Michael Roth
2012-08-14 16:27 ` [Qemu-devel] [PATCH 18/20] qidl: codegen, initial commit Michael Roth
2012-08-14 16:27 ` [Qemu-devel] [PATCH 19/20] qidl: qidl.h, definitions for qidl annotations Michael Roth
2012-08-14 16:27 ` [Qemu-devel] [PATCH 20/20] qidl: unit tests 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=1344961646-21194-6-git-send-email-mdroth@linux.vnet.ibm.com \
--to=mdroth@linux.vnet.ibm.com \
--cc=aliguori@us.ibm.com \
--cc=blauwirbel@gmail.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is 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).