qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH v2][ 05/21] qapi: add qapi-types.py code generat


From: Anthony Liguori
Subject: Re: [Qemu-devel] [PATCH v2][ 05/21] qapi: add qapi-types.py code generator
Date: Tue, 07 Jun 2011 14:54:17 -0500
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.17) Gecko/20110424 Lightning/1.0b2 Thunderbird/3.1.10

On 06/07/2011 02:12 PM, Luiz Capitulino wrote:
On Tue, 07 Jun 2011 14:06:53 -0500
Anthony Liguori<address@hidden>  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<address@hidden>
---
   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()







reply via email to

[Prev in Thread] Current Thread [Next in Thread]