diff options
author | Ian Campbell <ian.campbell@citrix.com> | 2010-08-19 15:20:22 +0100 |
---|---|---|
committer | Ian Campbell <ian.campbell@citrix.com> | 2010-08-19 15:20:22 +0100 |
commit | bcbf6e2049191fb218ff288106d0744430011dc9 (patch) | |
tree | 71c2df6b88cd195dd16acb201ed854dc9477c252 /tools/libxl/gentypes.py | |
parent | 735f084c0f41c313c07bcd345f0abf2850e90c4e (diff) | |
download | xen-bcbf6e2049191fb218ff288106d0744430011dc9.tar.gz xen-bcbf6e2049191fb218ff288106d0744430011dc9.tar.bz2 xen-bcbf6e2049191fb218ff288106d0744430011dc9.zip |
libxl: generate destructors for each libxl defined type
I chose the name "_destroy" rather than "_free" because the destructor
functions will free only the members of a type recursively but will
not free the actual type structure itself. The allocation of the type
is typically done by the caller and may not be a single allocation,
e.g. lists/arrays of types or embedded in other structures etc.
The exceptions to this rule are libxl_string_list_destroy and
libxl_key_value_list_destroy but I'm not 100% convinced they are
exceptions (since they are kind-of opaque) and I couldn't see a
cleanerway to express this concept. I have made a best effort attempt
to implement these functions sanely but since as far as I can tell
nothing in the current code base ever sets
libxl_domain_create_info.{xsdata,platformdata} I'm flying somewhat
blind.
[PATCH 05 of 16 of
libxl: autogenerate type definitions and destructor functions]
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
Diffstat (limited to 'tools/libxl/gentypes.py')
-rw-r--r-- | tools/libxl/gentypes.py | 78 |
1 files changed, 73 insertions, 5 deletions
diff --git a/tools/libxl/gentypes.py b/tools/libxl/gentypes.py index 5053d8dea7..e4762d3767 100644 --- a/tools/libxl/gentypes.py +++ b/tools/libxl/gentypes.py @@ -59,16 +59,53 @@ def libxl_C_type_define(ty, indent = ""): raise NotImplementedError("%s" % type(ty)) return s.replace("\n", "\n%s" % indent) +def libxl_C_type_destroy(ty, v, reference, indent = " ", parent = None): + if reference: + deref = v + "->" + else: + deref = v + "." + + s = "" + if isinstance(ty, libxltypes.KeyedUnion): + if parent is None: + raise Exception("KeyedUnion type must have a parent") + for f in ty.fields: + keyvar_expr = f.keyvar_expr % (parent + ty.keyvar_name) + s += "if (" + keyvar_expr + ") {\n" + s += libxl_C_type_destroy(f.type, deref + f.name, False, indent + " ", deref) + s += "}\n" + elif isinstance(ty, libxltypes.Reference): + s += libxl_C_type_destroy(ty.ref_type, v, True, indent, v) + elif isinstance(ty, libxltypes.Struct) and (parent is None or ty.destructor_fn is None): + for f in [f for f in ty.fields if not f.const]: + + if f.name is None: # Anonynous struct + s += libxl_C_type_destroy(f.type, deref, False, "", deref) + else: + s += libxl_C_type_destroy(f.type, deref + f.name, False, "", deref) + else: + if ty.passby == libxltypes.PASS_BY_REFERENCE and not reference: + makeref = "&" + else: + makeref = "" + + if ty.destructor_fn is not None: + s += "%s(%s);\n" % (ty.destructor_fn, makeref + v) + + if s != "": + s = indent + s + return s.replace("\n", "\n%s" % indent).rstrip(indent) + if __name__ == '__main__': - if len(sys.argv) < 3: - print >>sys.stderr, "Usage: gentypes.py <idl> <header>" + if len(sys.argv) < 4: + print >>sys.stderr, "Usage: gentypes.py <idl> <header> <implementation>" sys.exit(1) idl = sys.argv[1] (_,types) = libxltypes.parse(idl) header = sys.argv[2] - print "outputting libxl types to %s" % header + print "outputting libxl type definitions to %s" % header f = open(header, "w") @@ -84,8 +121,39 @@ if __name__ == '__main__': """ % " ".join(sys.argv)) - for t in types: - f.write(libxl_C_type_define(t) + ";\n") + for ty in types: + f.write(libxl_C_type_define(ty) + ";\n") + if ty.destructor_fn is not None: + f.write("void %s(%s *p);\n" % (ty.destructor_fn, ty.typename)) f.write("\n") f.write("""#endif /* __LIBXL_TYPES_H */\n""") + f.close() + + impl = sys.argv[3] + print "outputting libxl type implementations to %s" % impl + + f = open(impl, "w") + f.write(""" +/* DO NOT EDIT. + * + * This file is autogenerated by + * "%s" + */ + +#include "libxl_osdeps.h" + +#include <stdint.h> +#include <stdlib.h> + +#include "libxl.h" + +""" % " ".join(sys.argv)) + + for ty in [t for t in types if t.autogenerate_destructor]: + f.write("void %s(%s *p)\n" % (ty.destructor_fn, ty.typename)) + f.write("{\n") + f.write(libxl_C_type_destroy(ty, "p", True)) + f.write("}\n") + f.write("\n") + f.close() |