From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:38507) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QU2M4-00057p-Pz for qemu-devel@nongnu.org; Tue, 07 Jun 2011 15:54:26 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QU2M2-0005UH-Tr for qemu-devel@nongnu.org; Tue, 07 Jun 2011 15:54:24 -0400 Received: from mail-px0-f174.google.com ([209.85.212.174]:49739) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QU2M2-0005UC-GM for qemu-devel@nongnu.org; Tue, 07 Jun 2011 15:54:22 -0400 Received: by pxi15 with SMTP id 15so2059266pxi.33 for ; Tue, 07 Jun 2011 12:54:21 -0700 (PDT) Message-ID: <4DEE81E9.8070901@codemonkey.ws> Date: Tue, 07 Jun 2011 14:54:17 -0500 From: Anthony Liguori MIME-Version: 1.0 References: <1307140399-9023-1-git-send-email-mdroth@linux.vnet.ibm.com> <1307140399-9023-6-git-send-email-mdroth@linux.vnet.ibm.com> <4DEE76CD.9070405@codemonkey.ws> <20110607161203.42fc3601@doriath> In-Reply-To: <20110607161203.42fc3601@doriath> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [PATCH v2][ 05/21] qapi: add qapi-types.py code generator List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Luiz Capitulino Cc: Jes.Sorensen@redhat.com, agl@linux.vnet.ibm.com, Michael Roth , qemu-devel@nongnu.org On 06/07/2011 02:12 PM, Luiz Capitulino wrote: > On Tue, 07 Jun 2011 14:06:53 -0500 > Anthony Liguori 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 >>> --- >>> 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. Okay. I'll give folks some time to review. Regards, Anthony Liguori > >> >> 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() >> > >