On Tue, 07 Jun 2011 14:06:53 -0500 Anthony Liguori <anth...@codemonkey.ws> wrote:
> On 06/03/2011 05:33 PM, Michael Roth wrote: > > This is the code generator for qapi types. It will generation the > > following files: > > > > $(prefix)qapi-types.h - C types corresponding to types defined in > > the schema you pass in > > $(prefix)qapi-types.c - Cleanup functions for the above C types > > > > The $(prefix) is used to as a namespace to keep the generated code from > > one schema/code-generation separated from others so code and be > > generated from multiple schemas with clobbering previously created code. > > > > Signed-off-by: Michael Roth<mdr...@linux.vnet.ibm.com> > > --- > > scripts/qapi-types.py | 221 > > +++++++++++++++++++++++++++++++++++++++++++++++++ > > 1 files changed, 221 insertions(+), 0 deletions(-) > > create mode 100644 scripts/qapi-types.py > > > > diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py > > new file mode 100644 > > index 0000000..15603f3 > > --- /dev/null > > +++ b/scripts/qapi-types.py > > Other than copyright, I think this is ready to go. > > Haven't seen much comments about this series. I think we're at the > speak now or forever hold your peace moment, so if you've got concerns > about this approach, please speak up. Haven't started reviewing it yet, hope to start doing it tomorrow. > > Regards, > > Anthony Liguori > > > @@ -0,0 +1,221 @@ > > +from ordereddict import OrderedDict > > +from qapi import * > > +import sys > > +import os > > +import getopt > > + > > +def generate_fwd_struct(name, members): > > + return mcgen(''' > > +typedef struct %(name)s %(name)s; > > + > > +typedef struct %(name)sList > > +{ > > + %(name)s *value; > > + struct %(name)sList *next; > > +} %(name)sList; > > +''', > > + name=name) > > + > > +def generate_struct(structname, fieldname, members): > > + ret = mcgen(''' > > +struct %(name)s > > +{ > > +''', > > + name=structname) > > + > > + for argname, argentry, optional, structured in parse_args(members): > > + if optional: > > + ret += mcgen(''' > > + bool has_%(c_name)s; > > +''', > > + c_name=c_var(argname)) > > + if structured: > > + push_indent() > > + ret += generate_struct("", argname, argentry) > > + pop_indent() > > + else: > > + ret += mcgen(''' > > + %(c_type)s %(c_name)s; > > +''', > > + c_type=c_type(argentry), c_name=c_var(argname)) > > + > > + if len(fieldname): > > + fieldname = " " + fieldname > > + ret += mcgen(''' > > +}%(field)s; > > +''', > > + field=fieldname) > > + > > + return ret > > + > > +def generate_handle(name, typeinfo): > > + return mcgen(''' > > +typedef struct %(name)s > > +{ > > + %(c_type)s handle; > > +} %(name)s; > > + > > +typedef struct %(name)sList > > +{ > > + %(name)s *value; > > + struct %(name)sList *next; > > +} %(name)sList; > > +''', > > + name=name, c_type=c_type(typeinfo)) > > + > > +def generate_enum(name, values): > > + ret = mcgen(''' > > +typedef enum %(name)s > > +{ > > +''', > > + name=name) > > + > > + i = 1 > > + for value in values: > > + ret += mcgen(''' > > + %(abbrev)s_%(value)s = %(i)d, > > +''', > > + abbrev=de_camel_case(name).upper(), > > + value=c_var(value).upper(), > > + i=i) > > + i += 1 > > + > > + ret += mcgen(''' > > +} %(name)s; > > +''', > > + name=name) > > + > > + return ret > > + > > +def generate_union(name, typeinfo): > > + ret = mcgen(''' > > +struct %(name)s > > +{ > > + %(name)sKind kind; > > + union { > > +''', > > + name=name) > > + > > + for key in typeinfo: > > + ret += mcgen(''' > > + %(c_type)s %(c_name)s; > > +''', > > + c_type=c_type(typeinfo[key]), > > + c_name=c_var(key)) > > + > > + ret += mcgen(''' > > + }; > > +}; > > +''') > > + > > + return ret > > + > > +def generate_type_cleanup_decl(name): > > + ret = mcgen(''' > > +void qapi_free_%(type)s(%(c_type)s obj); > > +''', > > + c_type=c_type(name),type=name) > > + return ret > > + > > +def generate_type_cleanup(name): > > + ret = mcgen(''' > > +void qapi_free_%(type)s(%(c_type)s obj) > > +{ > > + QapiDeallocVisiter *md; > > + Visiter *v; > > + > > + if (!obj) { > > + return; > > + } > > + > > + md = qapi_dealloc_visiter_new(); > > + v = qapi_dealloc_get_visiter(md); > > + visit_type_%(type)s(v,&obj, NULL, NULL); > > + qapi_dealloc_visiter_cleanup(md); > > +} > > +''', > > + c_type=c_type(name),type=name) > > + return ret > > + > > + > > +try: > > + opts, args = getopt.gnu_getopt(sys.argv[1:], "p:o:", ["prefix=", > > "output-dir="]) > > +except getopt.GetoptError, err: > > + print str(err) > > + sys.exit(1) > > + > > +output_dir = "" > > +prefix = "" > > +c_file = 'qapi-types.c' > > +h_file = 'qapi-types.h' > > + > > +for o, a in opts: > > + if o in ("-p", "--prefix"): > > + prefix = a > > + elif o in ("-o", "--output-dir"): > > + output_dir = a + "/" > > + > > +c_file = output_dir + prefix + c_file > > +h_file = output_dir + prefix + h_file > > + > > +if os.path.isdir(output_dir) == False: > > + os.makedirs(output_dir) > > + > > +fdef = open(c_file, 'w') > > +fdecl = open(h_file, 'w') > > + > > +fdef.write(mcgen(''' > > +/* AUTOMATICALLY GENERATED, DO NOT MODIFY */ > > + > > +#include "qapi/qapi-dealloc-visiter.h" > > +#include "%(prefix)sqapi-types.h" > > +#include "%(prefix)sqapi-visit.h" > > + > > +''', prefix=prefix)) > > + > > +fdecl.write(mcgen(''' > > +/* AUTOMATICALLY GENERATED, DO NOT MODIFY */ > > +#ifndef %(guard)s > > +#define %(guard)s > > + > > +#include "qapi/qapi-types-core.h" > > +''', > > + guard=guardname(h_file))) > > + > > +exprs = parse_schema(sys.stdin) > > + > > +for expr in exprs: > > + ret = "\n" > > + if expr.has_key('type'): > > + ret += generate_fwd_struct(expr['type'], expr['data']) > > + elif expr.has_key('enum'): > > + add_enum(expr['enum']) > > + ret += generate_enum(expr['enum'], expr['data']) > > + elif expr.has_key('union'): > > + add_enum('%sKind' % expr['union']) > > + ret += generate_fwd_struct(expr['union'], expr['data']) + "\n" > > + ret += generate_enum('%sKind' % expr['union'], expr['data'].keys()) > > + else: > > + continue > > + fdecl.write(ret) > > + > > +for expr in exprs: > > + ret = "\n" > > + if expr.has_key('type'): > > + ret += generate_struct(expr['type'], "", expr['data']) + "\n" > > + ret += generate_type_cleanup_decl(expr['type']) > > + fdef.write(generate_type_cleanup(expr['type']) + "\n") > > + elif expr.has_key('handle'): > > + ret += generate_handle(expr['handle'], expr['data']) > > + elif expr.has_key('union'): > > + ret += generate_union(expr['union'], expr['data']) > > + else: > > + continue > > + fdecl.write(ret) > > + > > +fdecl.write(''' > > +#endif > > +''') > > + > > +fdecl.flush() > > +fdecl.close() >