[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 05/22] qapi: qapi_visit.py, support arrays and compl
From: |
Michael Roth |
Subject: |
[Qemu-devel] [PATCH 05/22] qapi: qapi_visit.py, support arrays and complex qapi definitions |
Date: |
Fri, 21 Sep 2012 09:07:28 -0500 |
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 <address@hidden>
Signed-off-by: Michael Roth <address@hidden>
---
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]:
+ 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);
+''',
+ 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
- [Qemu-devel] [PATCH v2] Add infrastructure for QIDL-based device serialization, Michael Roth, 2012/09/21
- [Qemu-devel] [PATCH 03/22] qapi: qapi-commands.py -> qapi_commands.py, Michael Roth, 2012/09/21
- [Qemu-devel] [PATCH 01/22] qapi: qapi-visit.py -> qapi_visit.py so we can import, Michael Roth, 2012/09/21
- [Qemu-devel] [PATCH 04/22] qapi: qapi_visit.py, make code useable as module, Michael Roth, 2012/09/21
- [Qemu-devel] [PATCH 02/22] qapi: qapi-types.py -> qapi_types.py, Michael Roth, 2012/09/21
- [Qemu-devel] [PATCH 09/22] qapi: QmpOutputVisitor, implement array handling, Michael Roth, 2012/09/21
- [Qemu-devel] [PATCH 08/22] qapi: add visitor interfaces for C arrays, Michael Roth, 2012/09/21
- [Qemu-devel] [PATCH 07/22] qapi: qapi_visit.py, support for visiting non-pointer/embedded structs, Michael Roth, 2012/09/21
- [Qemu-devel] [PATCH 06/22] qapi: qapi_visit.py, support generating static functions, Michael Roth, 2012/09/21
- [Qemu-devel] [PATCH 05/22] qapi: qapi_visit.py, support arrays and complex qapi definitions,
Michael Roth <=
- [Qemu-devel] [PATCH 11/22] qapi: qapi.py, make json parser more robust, Michael Roth, 2012/09/21
- [Qemu-devel] [PATCH 10/22] qapi: QmpInputVisitor, implement array handling, Michael Roth, 2012/09/21
- [Qemu-devel] [PATCH 13/22] qom-fuse: force single-threaded mode to avoid QMP races, Michael Roth, 2012/09/21
- [Qemu-devel] [PATCH 12/22] qapi: add open-coded visitor for struct tm types, Michael Roth, 2012/09/21
- [Qemu-devel] [PATCH 15/22] module additions for schema registration, Michael Roth, 2012/09/21
- [Qemu-devel] [PATCH 17/22] qidl: add documentation, Michael Roth, 2012/09/21
- [Qemu-devel] [PATCH 14/22] qom-fuse: workaround for truncated properties > 4096, Michael Roth, 2012/09/21
- [Qemu-devel] [PATCH 20/22] qidl: add QAPI-based code generator, Michael Roth, 2012/09/21
- [Qemu-devel] [PATCH 22/22] qidl: unit tests and build infrastructure, Michael Roth, 2012/09/21