Michael Roth <mdr...@linux.vnet.ibm.com> writes: Reviewed-by: Anthony Liguori <aligu...@us.ibm.com>
Regards, Anthony Liguori > 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. > > Signed-off-by: Michael Roth <mdr...@linux.vnet.ibm.com> > --- > scripts/qapi.py | 10 ++++++++-- > scripts/qapi_commands.py | 8 ++++---- > scripts/qapi_types.py | 2 +- > scripts/qapi_visit.py | 34 +++++++++++++++++++++++++++------- > 4 files changed, 40 insertions(+), 14 deletions(-) > > diff --git a/scripts/qapi.py b/scripts/qapi.py > index 8082af3..39bb74e 100644 > --- a/scripts/qapi.py > +++ b/scripts/qapi.py > @@ -99,12 +99,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 = '' > @@ -177,6 +181,8 @@ def c_type(name): > return 'void' > elif name == name.upper(): > return '%sEvent *' % camel_case(name) > + elif name.replace("u", "").replace("int", "") in ["8", "16", "32", "64"]: > + return name + "_t" > else: > return '%s *' % name > > diff --git a/scripts/qapi_commands.py b/scripts/qapi_commands.py > index 9eed40e..52221d6 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 4a734f5..fb2b9ea 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..9839e3c 100644 > --- a/scripts/qapi_visit.py > +++ b/scripts/qapi_visit.py > @@ -16,6 +16,22 @@ import sys > import os > import getopt > import errno > +import types > + > +def generate_visit_array_body(name, info): > + ret = mcgen(''' > +visit_start_array(m, (void **)obj, "%(name)s", %(count)s, sizeof(%(type)s), > errp); > +int %(name)s_i; > +for (%(name)s_i = 0; %(name)s_i < %(count)s; %(name)s_i++) { > + visit_type_%(type_short)s(m, &(*obj)->%(name)s[%(name)s_i], NULL, errp); > + visit_next_array(m, errp); > +} > +visit_end_array(m, errp); > +''', > + name=name, type=c_type(info['type'][0]), > + type_short=info['type'][0], > + count=info['array_size']) > + return ret > > def generate_visit_struct_body(field_prefix, name, members): > ret = mcgen(''' > @@ -45,10 +61,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 +74,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_array_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