Message ID | 1343150454-4677-2-git-send-email-mdroth@linux.vnet.ibm.com |
---|---|
State | New |
Headers | show |
Michael Roth <mdroth@linux.vnet.ibm.com> writes: Reviewed-by: Anthony Liguori <aliguori@us.ibm.com> Regards, Anthony Liguori > Python doesn't allow "-" in module names, so we need to rename the file > so we can re-use bits of the codegen > > Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com> > --- > Makefile | 4 +- > scripts/qapi-visit.py | 352 ------------------------------------------------- > scripts/qapi_visit.py | 352 +++++++++++++++++++++++++++++++++++++++++++++++++ > tests/Makefile | 4 +- > 4 files changed, 356 insertions(+), 356 deletions(-) > delete mode 100644 scripts/qapi-visit.py > create mode 100644 scripts/qapi_visit.py > > diff --git a/Makefile b/Makefile > index ab82ef3..ea7174c 100644 > --- a/Makefile > +++ b/Makefile > @@ -195,8 +195,8 @@ qapi-types.c qapi-types.h :\ > $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-types.py > $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py $(gen-out-type) -o "." < $<, " GEN $@") > qapi-visit.c qapi-visit.h :\ > -$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-visit.py > - $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py $(gen-out-type) -o "." < $<, " GEN $@") > +$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi_visit.py > + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi_visit.py $(gen-out-type) -o "." < $<, " GEN $@") > qmp-commands.h qmp-marshal.c :\ > $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py > $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py $(gen-out-type) -m -o "." < $<, " GEN $@") > diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py > deleted file mode 100644 > index 04ef7c4..0000000 > --- a/scripts/qapi-visit.py > +++ /dev/null > @@ -1,352 +0,0 @@ > -# > -# QAPI visitor generator > -# > -# Copyright IBM, Corp. 2011 > -# > -# Authors: > -# Anthony Liguori <aliguori@us.ibm.com> > -# Michael Roth <mdroth@linux.vnet.ibm.com> > -# > -# This work is licensed under the terms of the GNU GPLv2. > -# See the COPYING.LIB file in the top-level directory. > - > -from ordereddict import OrderedDict > -from qapi import * > -import sys > -import os > -import getopt > -import errno > - > -def generate_visit_struct_body(field_prefix, name, members): > - ret = mcgen(''' > -if (!error_is_set(errp)) { > -''') > - push_indent() > - > - if len(field_prefix): > - field_prefix = field_prefix + "." > - ret += mcgen(''' > -Error **errp = &err; /* from outer scope */ > -Error *err = NULL; > -visit_start_struct(m, NULL, "", "%(name)s", 0, &err); > -''', > - name=name) > - else: > - ret += mcgen(''' > -Error *err = NULL; > -visit_start_struct(m, (void **)obj, "%(name)s", name, sizeof(%(name)s), &err); > -''', > - name=name) > - > - ret += mcgen(''' > -if (!err) { > - if (!obj || *obj) { > -''') > - > - push_indent() > - push_indent() > - for argname, argentry, optional, structured in parse_args(members): > - if optional: > - ret += mcgen(''' > -visit_start_optional(m, obj ? &(*obj)->%(c_prefix)shas_%(c_name)s : NULL, "%(name)s", &err); > -if (obj && (*obj)->%(prefix)shas_%(c_name)s) { > -''', > - c_prefix=c_var(field_prefix), prefix=field_prefix, > - c_name=c_var(argname), name=argname) > - push_indent() > - > - 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); > -''', > - c_prefix=c_var(field_prefix), prefix=field_prefix, > - type=type_name(argentry), c_name=c_var(argname), > - name=argname) > - > - if optional: > - pop_indent() > - ret += mcgen(''' > -} > -visit_end_optional(m, &err); > -''') > - > - pop_indent() > - ret += mcgen(''' > - > - error_propagate(errp, err); > - err = NULL; > -} > -''') > - > - pop_indent() > - pop_indent() > - ret += mcgen(''' > - /* Always call end_struct if start_struct succeeded. */ > - visit_end_struct(m, &err); > - } > - error_propagate(errp, err); > -} > -''') > - return ret > - > -def generate_visit_struct(name, members): > - ret = mcgen(''' > - > -void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp) > -{ > -''', > - name=name) > - > - push_indent() > - ret += generate_visit_struct_body("", name, members) > - pop_indent() > - > - ret += mcgen(''' > -} > -''') > - return ret > - > -def generate_visit_list(name, members): > - return mcgen(''' > - > -void visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char *name, Error **errp) > -{ > - GenericList *i, **prev = (GenericList **)obj; > - Error *err = NULL; > - > - if (!error_is_set(errp)) { > - visit_start_list(m, name, &err); > - if (!err) { > - for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) { > - %(name)sList *native_i = (%(name)sList *)i; > - visit_type_%(name)s(m, &native_i->value, NULL, &err); > - } > - error_propagate(errp, err); > - err = NULL; > - > - /* Always call end_list if start_list succeeded. */ > - visit_end_list(m, &err); > - } > - error_propagate(errp, err); > - } > -} > -''', > - name=name) > - > -def generate_visit_enum(name, members): > - return mcgen(''' > - > -void visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error **errp) > -{ > - visit_type_enum(m, (int *)obj, %(name)s_lookup, "%(name)s", name, errp); > -} > -''', > - name=name) > - > -def generate_visit_union(name, members): > - ret = generate_visit_enum('%sKind' % name, members.keys()) > - > - ret += mcgen(''' > - > -void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp) > -{ > - Error *err = NULL; > - > - if (!error_is_set(errp)) { > - visit_start_struct(m, (void **)obj, "%(name)s", name, sizeof(%(name)s), &err); > - if (!err) { > - if (!obj || *obj) { > - visit_type_%(name)sKind(m, &(*obj)->kind, "type", &err); > - if (!err) { > - switch ((*obj)->kind) { > -''', > - name=name) > - > - push_indent() > - push_indent() > - for key in members: > - ret += mcgen(''' > - case %(abbrev)s_KIND_%(enum)s: > - visit_type_%(c_type)s(m, &(*obj)->%(c_name)s, "data", &err); > - break; > -''', > - abbrev = de_camel_case(name).upper(), > - enum = c_fun(de_camel_case(key)).upper(), > - c_type=members[key], > - c_name=c_fun(key)) > - > - ret += mcgen(''' > - default: > - abort(); > - } > - } > - error_propagate(errp, err); > - err = NULL; > - } > -''') > - pop_indent() > - ret += mcgen(''' > - /* Always call end_struct if start_struct succeeded. */ > - visit_end_struct(m, &err); > - } > - error_propagate(errp, err); > -} > -''') > - > - pop_indent(); > - ret += mcgen(''' > -} > -''') > - > - return ret > - > -def generate_declaration(name, members, genlist=True): > - ret = mcgen(''' > - > -void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp); > -''', > - name=name) > - > - if genlist: > - ret += mcgen(''' > -void visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char *name, Error **errp); > -''', > - name=name) > - > - return ret > - > -def generate_decl_enum(name, members, genlist=True): > - return mcgen(''' > - > -void visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error **errp); > -''', > - name=name) > - > -try: > - opts, args = getopt.gnu_getopt(sys.argv[1:], "chp:o:", > - ["source", "header", "prefix=", "output-dir="]) > -except getopt.GetoptError, err: > - print str(err) > - sys.exit(1) > - > -output_dir = "" > -prefix = "" > -c_file = 'qapi-visit.c' > -h_file = 'qapi-visit.h' > - > -do_c = False > -do_h = False > - > -for o, a in opts: > - if o in ("-p", "--prefix"): > - prefix = a > - elif o in ("-o", "--output-dir"): > - output_dir = a + "/" > - elif o in ("-c", "--source"): > - do_c = True > - elif o in ("-h", "--header"): > - do_h = True > - > -if not do_c and not do_h: > - do_c = True > - do_h = True > - > -c_file = output_dir + prefix + c_file > -h_file = output_dir + prefix + h_file > - > -try: > - os.makedirs(output_dir) > -except os.error, e: > - if e.errno != errno.EEXIST: > - raise > - > -def maybe_open(really, name, opt): > - if really: > - return open(name, opt) > - else: > - import StringIO > - return StringIO.StringIO() > - > -fdef = maybe_open(do_c, c_file, 'w') > -fdecl = maybe_open(do_h, h_file, 'w') > - > -fdef.write(mcgen(''' > -/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */ > - > -/* > - * schema-defined QAPI visitor functions > - * > - * Copyright IBM, Corp. 2011 > - * > - * Authors: > - * Anthony Liguori <aliguori@us.ibm.com> > - * > - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. > - * See the COPYING.LIB file in the top-level directory. > - * > - */ > - > -#include "%(header)s" > -''', > - header=basename(h_file))) > - > -fdecl.write(mcgen(''' > -/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */ > - > -/* > - * schema-defined QAPI visitor function > - * > - * Copyright IBM, Corp. 2011 > - * > - * Authors: > - * Anthony Liguori <aliguori@us.ibm.com> > - * > - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. > - * See the COPYING.LIB file in the top-level directory. > - * > - */ > - > -#ifndef %(guard)s > -#define %(guard)s > - > -#include "qapi/qapi-visit-core.h" > -#include "%(prefix)sqapi-types.h" > -''', > - prefix=prefix, guard=guardname(h_file))) > - > -exprs = parse_schema(sys.stdin) > - > -for expr in exprs: > - if expr.has_key('type'): > - ret = generate_visit_struct(expr['type'], expr['data']) > - ret += generate_visit_list(expr['type'], expr['data']) > - fdef.write(ret) > - > - ret = generate_declaration(expr['type'], expr['data']) > - fdecl.write(ret) > - elif expr.has_key('union'): > - ret = generate_visit_union(expr['union'], expr['data']) > - ret += generate_visit_list(expr['union'], expr['data']) > - fdef.write(ret) > - > - ret = generate_decl_enum('%sKind' % expr['union'], expr['data'].keys()) > - ret += generate_declaration(expr['union'], expr['data']) > - fdecl.write(ret) > - elif expr.has_key('enum'): > - ret = generate_visit_enum(expr['enum'], expr['data']) > - fdef.write(ret) > - > - ret = generate_decl_enum(expr['enum'], expr['data']) > - fdecl.write(ret) > - > -fdecl.write(''' > -#endif > -''') > - > -fdecl.flush() > -fdecl.close() > - > -fdef.flush() > -fdef.close() > diff --git a/scripts/qapi_visit.py b/scripts/qapi_visit.py > new file mode 100644 > index 0000000..04ef7c4 > --- /dev/null > +++ b/scripts/qapi_visit.py > @@ -0,0 +1,352 @@ > +# > +# QAPI visitor generator > +# > +# Copyright IBM, Corp. 2011 > +# > +# Authors: > +# Anthony Liguori <aliguori@us.ibm.com> > +# Michael Roth <mdroth@linux.vnet.ibm.com> > +# > +# This work is licensed under the terms of the GNU GPLv2. > +# See the COPYING.LIB file in the top-level directory. > + > +from ordereddict import OrderedDict > +from qapi import * > +import sys > +import os > +import getopt > +import errno > + > +def generate_visit_struct_body(field_prefix, name, members): > + ret = mcgen(''' > +if (!error_is_set(errp)) { > +''') > + push_indent() > + > + if len(field_prefix): > + field_prefix = field_prefix + "." > + ret += mcgen(''' > +Error **errp = &err; /* from outer scope */ > +Error *err = NULL; > +visit_start_struct(m, NULL, "", "%(name)s", 0, &err); > +''', > + name=name) > + else: > + ret += mcgen(''' > +Error *err = NULL; > +visit_start_struct(m, (void **)obj, "%(name)s", name, sizeof(%(name)s), &err); > +''', > + name=name) > + > + ret += mcgen(''' > +if (!err) { > + if (!obj || *obj) { > +''') > + > + push_indent() > + push_indent() > + for argname, argentry, optional, structured in parse_args(members): > + if optional: > + ret += mcgen(''' > +visit_start_optional(m, obj ? &(*obj)->%(c_prefix)shas_%(c_name)s : NULL, "%(name)s", &err); > +if (obj && (*obj)->%(prefix)shas_%(c_name)s) { > +''', > + c_prefix=c_var(field_prefix), prefix=field_prefix, > + c_name=c_var(argname), name=argname) > + push_indent() > + > + 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); > +''', > + c_prefix=c_var(field_prefix), prefix=field_prefix, > + type=type_name(argentry), c_name=c_var(argname), > + name=argname) > + > + if optional: > + pop_indent() > + ret += mcgen(''' > +} > +visit_end_optional(m, &err); > +''') > + > + pop_indent() > + ret += mcgen(''' > + > + error_propagate(errp, err); > + err = NULL; > +} > +''') > + > + pop_indent() > + pop_indent() > + ret += mcgen(''' > + /* Always call end_struct if start_struct succeeded. */ > + visit_end_struct(m, &err); > + } > + error_propagate(errp, err); > +} > +''') > + return ret > + > +def generate_visit_struct(name, members): > + ret = mcgen(''' > + > +void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp) > +{ > +''', > + name=name) > + > + push_indent() > + ret += generate_visit_struct_body("", name, members) > + pop_indent() > + > + ret += mcgen(''' > +} > +''') > + return ret > + > +def generate_visit_list(name, members): > + return mcgen(''' > + > +void visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char *name, Error **errp) > +{ > + GenericList *i, **prev = (GenericList **)obj; > + Error *err = NULL; > + > + if (!error_is_set(errp)) { > + visit_start_list(m, name, &err); > + if (!err) { > + for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) { > + %(name)sList *native_i = (%(name)sList *)i; > + visit_type_%(name)s(m, &native_i->value, NULL, &err); > + } > + error_propagate(errp, err); > + err = NULL; > + > + /* Always call end_list if start_list succeeded. */ > + visit_end_list(m, &err); > + } > + error_propagate(errp, err); > + } > +} > +''', > + name=name) > + > +def generate_visit_enum(name, members): > + return mcgen(''' > + > +void visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error **errp) > +{ > + visit_type_enum(m, (int *)obj, %(name)s_lookup, "%(name)s", name, errp); > +} > +''', > + name=name) > + > +def generate_visit_union(name, members): > + ret = generate_visit_enum('%sKind' % name, members.keys()) > + > + ret += mcgen(''' > + > +void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp) > +{ > + Error *err = NULL; > + > + if (!error_is_set(errp)) { > + visit_start_struct(m, (void **)obj, "%(name)s", name, sizeof(%(name)s), &err); > + if (!err) { > + if (!obj || *obj) { > + visit_type_%(name)sKind(m, &(*obj)->kind, "type", &err); > + if (!err) { > + switch ((*obj)->kind) { > +''', > + name=name) > + > + push_indent() > + push_indent() > + for key in members: > + ret += mcgen(''' > + case %(abbrev)s_KIND_%(enum)s: > + visit_type_%(c_type)s(m, &(*obj)->%(c_name)s, "data", &err); > + break; > +''', > + abbrev = de_camel_case(name).upper(), > + enum = c_fun(de_camel_case(key)).upper(), > + c_type=members[key], > + c_name=c_fun(key)) > + > + ret += mcgen(''' > + default: > + abort(); > + } > + } > + error_propagate(errp, err); > + err = NULL; > + } > +''') > + pop_indent() > + ret += mcgen(''' > + /* Always call end_struct if start_struct succeeded. */ > + visit_end_struct(m, &err); > + } > + error_propagate(errp, err); > +} > +''') > + > + pop_indent(); > + ret += mcgen(''' > +} > +''') > + > + return ret > + > +def generate_declaration(name, members, genlist=True): > + ret = mcgen(''' > + > +void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp); > +''', > + name=name) > + > + if genlist: > + ret += mcgen(''' > +void visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char *name, Error **errp); > +''', > + name=name) > + > + return ret > + > +def generate_decl_enum(name, members, genlist=True): > + return mcgen(''' > + > +void visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error **errp); > +''', > + name=name) > + > +try: > + opts, args = getopt.gnu_getopt(sys.argv[1:], "chp:o:", > + ["source", "header", "prefix=", "output-dir="]) > +except getopt.GetoptError, err: > + print str(err) > + sys.exit(1) > + > +output_dir = "" > +prefix = "" > +c_file = 'qapi-visit.c' > +h_file = 'qapi-visit.h' > + > +do_c = False > +do_h = False > + > +for o, a in opts: > + if o in ("-p", "--prefix"): > + prefix = a > + elif o in ("-o", "--output-dir"): > + output_dir = a + "/" > + elif o in ("-c", "--source"): > + do_c = True > + elif o in ("-h", "--header"): > + do_h = True > + > +if not do_c and not do_h: > + do_c = True > + do_h = True > + > +c_file = output_dir + prefix + c_file > +h_file = output_dir + prefix + h_file > + > +try: > + os.makedirs(output_dir) > +except os.error, e: > + if e.errno != errno.EEXIST: > + raise > + > +def maybe_open(really, name, opt): > + if really: > + return open(name, opt) > + else: > + import StringIO > + return StringIO.StringIO() > + > +fdef = maybe_open(do_c, c_file, 'w') > +fdecl = maybe_open(do_h, h_file, 'w') > + > +fdef.write(mcgen(''' > +/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */ > + > +/* > + * schema-defined QAPI visitor functions > + * > + * Copyright IBM, Corp. 2011 > + * > + * Authors: > + * Anthony Liguori <aliguori@us.ibm.com> > + * > + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. > + * See the COPYING.LIB file in the top-level directory. > + * > + */ > + > +#include "%(header)s" > +''', > + header=basename(h_file))) > + > +fdecl.write(mcgen(''' > +/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */ > + > +/* > + * schema-defined QAPI visitor function > + * > + * Copyright IBM, Corp. 2011 > + * > + * Authors: > + * Anthony Liguori <aliguori@us.ibm.com> > + * > + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. > + * See the COPYING.LIB file in the top-level directory. > + * > + */ > + > +#ifndef %(guard)s > +#define %(guard)s > + > +#include "qapi/qapi-visit-core.h" > +#include "%(prefix)sqapi-types.h" > +''', > + prefix=prefix, guard=guardname(h_file))) > + > +exprs = parse_schema(sys.stdin) > + > +for expr in exprs: > + if expr.has_key('type'): > + ret = generate_visit_struct(expr['type'], expr['data']) > + ret += generate_visit_list(expr['type'], expr['data']) > + fdef.write(ret) > + > + ret = generate_declaration(expr['type'], expr['data']) > + fdecl.write(ret) > + elif expr.has_key('union'): > + ret = generate_visit_union(expr['union'], expr['data']) > + ret += generate_visit_list(expr['union'], expr['data']) > + fdef.write(ret) > + > + ret = generate_decl_enum('%sKind' % expr['union'], expr['data'].keys()) > + ret += generate_declaration(expr['union'], expr['data']) > + fdecl.write(ret) > + elif expr.has_key('enum'): > + ret = generate_visit_enum(expr['enum'], expr['data']) > + fdef.write(ret) > + > + ret = generate_decl_enum(expr['enum'], expr['data']) > + fdecl.write(ret) > + > +fdecl.write(''' > +#endif > +''') > + > +fdecl.flush() > +fdecl.close() > + > +fdef.flush() > +fdef.close() > diff --git a/tests/Makefile b/tests/Makefile > index 9675ba7..8bbac75 100644 > --- a/tests/Makefile > +++ b/tests/Makefile > @@ -55,8 +55,8 @@ tests/test-qapi-types.c tests/test-qapi-types.h :\ > $(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-types.py > $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py $(gen-out-type) -o tests -p "test-" < $<, " GEN $@") > tests/test-qapi-visit.c tests/test-qapi-visit.h :\ > -$(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-visit.py > - $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py $(gen-out-type) -o tests -p "test-" < $<, " GEN $@") > +$(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi_visit.py > + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi_visit.py $(gen-out-type) -o tests -p "test-" < $<, " GEN $@") > tests/test-qmp-commands.h tests/test-qmp-marshal.c :\ > $(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-commands.py > $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py $(gen-out-type) -o tests -p "test-" < $<, " GEN $@") > -- > 1.7.9.5
diff --git a/Makefile b/Makefile index ab82ef3..ea7174c 100644 --- a/Makefile +++ b/Makefile @@ -195,8 +195,8 @@ qapi-types.c qapi-types.h :\ $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-types.py $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py $(gen-out-type) -o "." < $<, " GEN $@") qapi-visit.c qapi-visit.h :\ -$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-visit.py - $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py $(gen-out-type) -o "." < $<, " GEN $@") +$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi_visit.py + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi_visit.py $(gen-out-type) -o "." < $<, " GEN $@") qmp-commands.h qmp-marshal.c :\ $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py $(gen-out-type) -m -o "." < $<, " GEN $@") diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py deleted file mode 100644 index 04ef7c4..0000000 --- a/scripts/qapi-visit.py +++ /dev/null @@ -1,352 +0,0 @@ -# -# QAPI visitor generator -# -# Copyright IBM, Corp. 2011 -# -# Authors: -# Anthony Liguori <aliguori@us.ibm.com> -# Michael Roth <mdroth@linux.vnet.ibm.com> -# -# This work is licensed under the terms of the GNU GPLv2. -# See the COPYING.LIB file in the top-level directory. - -from ordereddict import OrderedDict -from qapi import * -import sys -import os -import getopt -import errno - -def generate_visit_struct_body(field_prefix, name, members): - ret = mcgen(''' -if (!error_is_set(errp)) { -''') - push_indent() - - if len(field_prefix): - field_prefix = field_prefix + "." - ret += mcgen(''' -Error **errp = &err; /* from outer scope */ -Error *err = NULL; -visit_start_struct(m, NULL, "", "%(name)s", 0, &err); -''', - name=name) - else: - ret += mcgen(''' -Error *err = NULL; -visit_start_struct(m, (void **)obj, "%(name)s", name, sizeof(%(name)s), &err); -''', - name=name) - - ret += mcgen(''' -if (!err) { - if (!obj || *obj) { -''') - - push_indent() - push_indent() - for argname, argentry, optional, structured in parse_args(members): - if optional: - ret += mcgen(''' -visit_start_optional(m, obj ? &(*obj)->%(c_prefix)shas_%(c_name)s : NULL, "%(name)s", &err); -if (obj && (*obj)->%(prefix)shas_%(c_name)s) { -''', - c_prefix=c_var(field_prefix), prefix=field_prefix, - c_name=c_var(argname), name=argname) - push_indent() - - 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); -''', - c_prefix=c_var(field_prefix), prefix=field_prefix, - type=type_name(argentry), c_name=c_var(argname), - name=argname) - - if optional: - pop_indent() - ret += mcgen(''' -} -visit_end_optional(m, &err); -''') - - pop_indent() - ret += mcgen(''' - - error_propagate(errp, err); - err = NULL; -} -''') - - pop_indent() - pop_indent() - ret += mcgen(''' - /* Always call end_struct if start_struct succeeded. */ - visit_end_struct(m, &err); - } - error_propagate(errp, err); -} -''') - return ret - -def generate_visit_struct(name, members): - ret = mcgen(''' - -void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp) -{ -''', - name=name) - - push_indent() - ret += generate_visit_struct_body("", name, members) - pop_indent() - - ret += mcgen(''' -} -''') - return ret - -def generate_visit_list(name, members): - return mcgen(''' - -void visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char *name, Error **errp) -{ - GenericList *i, **prev = (GenericList **)obj; - Error *err = NULL; - - if (!error_is_set(errp)) { - visit_start_list(m, name, &err); - if (!err) { - for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) { - %(name)sList *native_i = (%(name)sList *)i; - visit_type_%(name)s(m, &native_i->value, NULL, &err); - } - error_propagate(errp, err); - err = NULL; - - /* Always call end_list if start_list succeeded. */ - visit_end_list(m, &err); - } - error_propagate(errp, err); - } -} -''', - name=name) - -def generate_visit_enum(name, members): - return mcgen(''' - -void visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error **errp) -{ - visit_type_enum(m, (int *)obj, %(name)s_lookup, "%(name)s", name, errp); -} -''', - name=name) - -def generate_visit_union(name, members): - ret = generate_visit_enum('%sKind' % name, members.keys()) - - ret += mcgen(''' - -void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp) -{ - Error *err = NULL; - - if (!error_is_set(errp)) { - visit_start_struct(m, (void **)obj, "%(name)s", name, sizeof(%(name)s), &err); - if (!err) { - if (!obj || *obj) { - visit_type_%(name)sKind(m, &(*obj)->kind, "type", &err); - if (!err) { - switch ((*obj)->kind) { -''', - name=name) - - push_indent() - push_indent() - for key in members: - ret += mcgen(''' - case %(abbrev)s_KIND_%(enum)s: - visit_type_%(c_type)s(m, &(*obj)->%(c_name)s, "data", &err); - break; -''', - abbrev = de_camel_case(name).upper(), - enum = c_fun(de_camel_case(key)).upper(), - c_type=members[key], - c_name=c_fun(key)) - - ret += mcgen(''' - default: - abort(); - } - } - error_propagate(errp, err); - err = NULL; - } -''') - pop_indent() - ret += mcgen(''' - /* Always call end_struct if start_struct succeeded. */ - visit_end_struct(m, &err); - } - error_propagate(errp, err); -} -''') - - pop_indent(); - ret += mcgen(''' -} -''') - - return ret - -def generate_declaration(name, members, genlist=True): - ret = mcgen(''' - -void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp); -''', - name=name) - - if genlist: - ret += mcgen(''' -void visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char *name, Error **errp); -''', - name=name) - - return ret - -def generate_decl_enum(name, members, genlist=True): - return mcgen(''' - -void visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error **errp); -''', - name=name) - -try: - opts, args = getopt.gnu_getopt(sys.argv[1:], "chp:o:", - ["source", "header", "prefix=", "output-dir="]) -except getopt.GetoptError, err: - print str(err) - sys.exit(1) - -output_dir = "" -prefix = "" -c_file = 'qapi-visit.c' -h_file = 'qapi-visit.h' - -do_c = False -do_h = False - -for o, a in opts: - if o in ("-p", "--prefix"): - prefix = a - elif o in ("-o", "--output-dir"): - output_dir = a + "/" - elif o in ("-c", "--source"): - do_c = True - elif o in ("-h", "--header"): - do_h = True - -if not do_c and not do_h: - do_c = True - do_h = True - -c_file = output_dir + prefix + c_file -h_file = output_dir + prefix + h_file - -try: - os.makedirs(output_dir) -except os.error, e: - if e.errno != errno.EEXIST: - raise - -def maybe_open(really, name, opt): - if really: - return open(name, opt) - else: - import StringIO - return StringIO.StringIO() - -fdef = maybe_open(do_c, c_file, 'w') -fdecl = maybe_open(do_h, h_file, 'w') - -fdef.write(mcgen(''' -/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */ - -/* - * schema-defined QAPI visitor functions - * - * Copyright IBM, Corp. 2011 - * - * Authors: - * Anthony Liguori <aliguori@us.ibm.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. - * See the COPYING.LIB file in the top-level directory. - * - */ - -#include "%(header)s" -''', - header=basename(h_file))) - -fdecl.write(mcgen(''' -/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */ - -/* - * schema-defined QAPI visitor function - * - * Copyright IBM, Corp. 2011 - * - * Authors: - * Anthony Liguori <aliguori@us.ibm.com> - * - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. - * See the COPYING.LIB file in the top-level directory. - * - */ - -#ifndef %(guard)s -#define %(guard)s - -#include "qapi/qapi-visit-core.h" -#include "%(prefix)sqapi-types.h" -''', - prefix=prefix, guard=guardname(h_file))) - -exprs = parse_schema(sys.stdin) - -for expr in exprs: - if expr.has_key('type'): - ret = generate_visit_struct(expr['type'], expr['data']) - ret += generate_visit_list(expr['type'], expr['data']) - fdef.write(ret) - - ret = generate_declaration(expr['type'], expr['data']) - fdecl.write(ret) - elif expr.has_key('union'): - ret = generate_visit_union(expr['union'], expr['data']) - ret += generate_visit_list(expr['union'], expr['data']) - fdef.write(ret) - - ret = generate_decl_enum('%sKind' % expr['union'], expr['data'].keys()) - ret += generate_declaration(expr['union'], expr['data']) - fdecl.write(ret) - elif expr.has_key('enum'): - ret = generate_visit_enum(expr['enum'], expr['data']) - fdef.write(ret) - - ret = generate_decl_enum(expr['enum'], expr['data']) - fdecl.write(ret) - -fdecl.write(''' -#endif -''') - -fdecl.flush() -fdecl.close() - -fdef.flush() -fdef.close() diff --git a/scripts/qapi_visit.py b/scripts/qapi_visit.py new file mode 100644 index 0000000..04ef7c4 --- /dev/null +++ b/scripts/qapi_visit.py @@ -0,0 +1,352 @@ +# +# QAPI visitor generator +# +# Copyright IBM, Corp. 2011 +# +# Authors: +# Anthony Liguori <aliguori@us.ibm.com> +# Michael Roth <mdroth@linux.vnet.ibm.com> +# +# This work is licensed under the terms of the GNU GPLv2. +# See the COPYING.LIB file in the top-level directory. + +from ordereddict import OrderedDict +from qapi import * +import sys +import os +import getopt +import errno + +def generate_visit_struct_body(field_prefix, name, members): + ret = mcgen(''' +if (!error_is_set(errp)) { +''') + push_indent() + + if len(field_prefix): + field_prefix = field_prefix + "." + ret += mcgen(''' +Error **errp = &err; /* from outer scope */ +Error *err = NULL; +visit_start_struct(m, NULL, "", "%(name)s", 0, &err); +''', + name=name) + else: + ret += mcgen(''' +Error *err = NULL; +visit_start_struct(m, (void **)obj, "%(name)s", name, sizeof(%(name)s), &err); +''', + name=name) + + ret += mcgen(''' +if (!err) { + if (!obj || *obj) { +''') + + push_indent() + push_indent() + for argname, argentry, optional, structured in parse_args(members): + if optional: + ret += mcgen(''' +visit_start_optional(m, obj ? &(*obj)->%(c_prefix)shas_%(c_name)s : NULL, "%(name)s", &err); +if (obj && (*obj)->%(prefix)shas_%(c_name)s) { +''', + c_prefix=c_var(field_prefix), prefix=field_prefix, + c_name=c_var(argname), name=argname) + push_indent() + + 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); +''', + c_prefix=c_var(field_prefix), prefix=field_prefix, + type=type_name(argentry), c_name=c_var(argname), + name=argname) + + if optional: + pop_indent() + ret += mcgen(''' +} +visit_end_optional(m, &err); +''') + + pop_indent() + ret += mcgen(''' + + error_propagate(errp, err); + err = NULL; +} +''') + + pop_indent() + pop_indent() + ret += mcgen(''' + /* Always call end_struct if start_struct succeeded. */ + visit_end_struct(m, &err); + } + error_propagate(errp, err); +} +''') + return ret + +def generate_visit_struct(name, members): + ret = mcgen(''' + +void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp) +{ +''', + name=name) + + push_indent() + ret += generate_visit_struct_body("", name, members) + pop_indent() + + ret += mcgen(''' +} +''') + return ret + +def generate_visit_list(name, members): + return mcgen(''' + +void visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char *name, Error **errp) +{ + GenericList *i, **prev = (GenericList **)obj; + Error *err = NULL; + + if (!error_is_set(errp)) { + visit_start_list(m, name, &err); + if (!err) { + for (; (i = visit_next_list(m, prev, &err)) != NULL; prev = &i) { + %(name)sList *native_i = (%(name)sList *)i; + visit_type_%(name)s(m, &native_i->value, NULL, &err); + } + error_propagate(errp, err); + err = NULL; + + /* Always call end_list if start_list succeeded. */ + visit_end_list(m, &err); + } + error_propagate(errp, err); + } +} +''', + name=name) + +def generate_visit_enum(name, members): + return mcgen(''' + +void visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error **errp) +{ + visit_type_enum(m, (int *)obj, %(name)s_lookup, "%(name)s", name, errp); +} +''', + name=name) + +def generate_visit_union(name, members): + ret = generate_visit_enum('%sKind' % name, members.keys()) + + ret += mcgen(''' + +void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp) +{ + Error *err = NULL; + + if (!error_is_set(errp)) { + visit_start_struct(m, (void **)obj, "%(name)s", name, sizeof(%(name)s), &err); + if (!err) { + if (!obj || *obj) { + visit_type_%(name)sKind(m, &(*obj)->kind, "type", &err); + if (!err) { + switch ((*obj)->kind) { +''', + name=name) + + push_indent() + push_indent() + for key in members: + ret += mcgen(''' + case %(abbrev)s_KIND_%(enum)s: + visit_type_%(c_type)s(m, &(*obj)->%(c_name)s, "data", &err); + break; +''', + abbrev = de_camel_case(name).upper(), + enum = c_fun(de_camel_case(key)).upper(), + c_type=members[key], + c_name=c_fun(key)) + + ret += mcgen(''' + default: + abort(); + } + } + error_propagate(errp, err); + err = NULL; + } +''') + pop_indent() + ret += mcgen(''' + /* Always call end_struct if start_struct succeeded. */ + visit_end_struct(m, &err); + } + error_propagate(errp, err); +} +''') + + pop_indent(); + ret += mcgen(''' +} +''') + + return ret + +def generate_declaration(name, members, genlist=True): + ret = mcgen(''' + +void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp); +''', + name=name) + + if genlist: + ret += mcgen(''' +void visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char *name, Error **errp); +''', + name=name) + + return ret + +def generate_decl_enum(name, members, genlist=True): + return mcgen(''' + +void visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error **errp); +''', + name=name) + +try: + opts, args = getopt.gnu_getopt(sys.argv[1:], "chp:o:", + ["source", "header", "prefix=", "output-dir="]) +except getopt.GetoptError, err: + print str(err) + sys.exit(1) + +output_dir = "" +prefix = "" +c_file = 'qapi-visit.c' +h_file = 'qapi-visit.h' + +do_c = False +do_h = False + +for o, a in opts: + if o in ("-p", "--prefix"): + prefix = a + elif o in ("-o", "--output-dir"): + output_dir = a + "/" + elif o in ("-c", "--source"): + do_c = True + elif o in ("-h", "--header"): + do_h = True + +if not do_c and not do_h: + do_c = True + do_h = True + +c_file = output_dir + prefix + c_file +h_file = output_dir + prefix + h_file + +try: + os.makedirs(output_dir) +except os.error, e: + if e.errno != errno.EEXIST: + raise + +def maybe_open(really, name, opt): + if really: + return open(name, opt) + else: + import StringIO + return StringIO.StringIO() + +fdef = maybe_open(do_c, c_file, 'w') +fdecl = maybe_open(do_h, h_file, 'w') + +fdef.write(mcgen(''' +/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */ + +/* + * schema-defined QAPI visitor functions + * + * Copyright IBM, Corp. 2011 + * + * Authors: + * Anthony Liguori <aliguori@us.ibm.com> + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. + * See the COPYING.LIB file in the top-level directory. + * + */ + +#include "%(header)s" +''', + header=basename(h_file))) + +fdecl.write(mcgen(''' +/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */ + +/* + * schema-defined QAPI visitor function + * + * Copyright IBM, Corp. 2011 + * + * Authors: + * Anthony Liguori <aliguori@us.ibm.com> + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. + * See the COPYING.LIB file in the top-level directory. + * + */ + +#ifndef %(guard)s +#define %(guard)s + +#include "qapi/qapi-visit-core.h" +#include "%(prefix)sqapi-types.h" +''', + prefix=prefix, guard=guardname(h_file))) + +exprs = parse_schema(sys.stdin) + +for expr in exprs: + if expr.has_key('type'): + ret = generate_visit_struct(expr['type'], expr['data']) + ret += generate_visit_list(expr['type'], expr['data']) + fdef.write(ret) + + ret = generate_declaration(expr['type'], expr['data']) + fdecl.write(ret) + elif expr.has_key('union'): + ret = generate_visit_union(expr['union'], expr['data']) + ret += generate_visit_list(expr['union'], expr['data']) + fdef.write(ret) + + ret = generate_decl_enum('%sKind' % expr['union'], expr['data'].keys()) + ret += generate_declaration(expr['union'], expr['data']) + fdecl.write(ret) + elif expr.has_key('enum'): + ret = generate_visit_enum(expr['enum'], expr['data']) + fdef.write(ret) + + ret = generate_decl_enum(expr['enum'], expr['data']) + fdecl.write(ret) + +fdecl.write(''' +#endif +''') + +fdecl.flush() +fdecl.close() + +fdef.flush() +fdef.close() diff --git a/tests/Makefile b/tests/Makefile index 9675ba7..8bbac75 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -55,8 +55,8 @@ tests/test-qapi-types.c tests/test-qapi-types.h :\ $(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-types.py $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py $(gen-out-type) -o tests -p "test-" < $<, " GEN $@") tests/test-qapi-visit.c tests/test-qapi-visit.h :\ -$(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-visit.py - $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py $(gen-out-type) -o tests -p "test-" < $<, " GEN $@") +$(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi_visit.py + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi_visit.py $(gen-out-type) -o tests -p "test-" < $<, " GEN $@") tests/test-qmp-commands.h tests/test-qmp-marshal.c :\ $(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-commands.py $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py $(gen-out-type) -o tests -p "test-" < $<, " GEN $@")
Python doesn't allow "-" in module names, so we need to rename the file so we can re-use bits of the codegen Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com> --- Makefile | 4 +- scripts/qapi-visit.py | 352 ------------------------------------------------- scripts/qapi_visit.py | 352 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/Makefile | 4 +- 4 files changed, 356 insertions(+), 356 deletions(-) delete mode 100644 scripts/qapi-visit.py create mode 100644 scripts/qapi_visit.py