# HG changeset patch
# User Ian Campbell <ian.campbell@xxxxxxxxxx>
# Date 1280829586 -3600
# Node ID 6baa8ce2ec5ed5d140a67b87d2514e88464df34e
# Parent 5d51a404379e3e91c08c07c8292abefa1440a655
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 strucutures etc.
Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
diff -r 5d51a404379e -r 6baa8ce2ec5e .hgignore
--- a/.hgignore Tue Aug 03 10:59:46 2010 +0100
+++ b/.hgignore Tue Aug 03 10:59:46 2010 +0100
@@ -182,6 +182,7 @@
^tools/libxen/test/test_bindings$
^tools/libxen/test/test_event_handling$
^tools/libxl/_.*\.h$
+^tools/libxl/_.*\.c$
^tools/libxl/libxlu_cfg_y\.output$
^tools/libxl/xl$
^tools/libaio/src/.*\.ol$
diff -r 5d51a404379e -r 6baa8ce2ec5e tools/libxl/Makefile
--- a/tools/libxl/Makefile Tue Aug 03 10:59:46 2010 +0100
+++ b/tools/libxl/Makefile Tue Aug 03 10:59:46 2010 +0100
@@ -19,6 +19,7 @@ LIBS = $(LDFLAGS_libxenctrl) $(LDFLAGS_l
LIBXL_OBJS-y = osdeps.o libxl_paths.o libxl_bootloader.o
LIBXL_OBJS = flexarray.o libxl.o libxl_pci.o libxl_dom.o libxl_exec.o
libxl_xshelp.o libxl_device.o libxl_internal.o xenguest.o libxl_utils.o
$(LIBXL_OBJS-y)
+LIBXL_OBJS += _libxl_types.c
AUTOINCS= libxlu_cfg_y.h libxlu_cfg_l.h
AUTOSRCS= libxlu_cfg_y.c libxlu_cfg_l.c
@@ -54,9 +55,10 @@ libxl_paths.c: _libxl_paths.h
libxl.h: _libxl_types.h
-_libxl_types.h: gentypes.py libxltypes.py
- python gentypes.py __libxl_types.h
+_libxl_types.h _libxl_types.c: gentypes.py libxltypes.py
+ python gentypes.py __libxl_types.h __libxl_types.c
mv __libxl_types.h _libxl_types.h
+ mv __libxl_types.c _libxl_types.c
libxenlight.so: libxenlight.so.$(MAJOR)
ln -sf $< $@
@@ -115,6 +117,7 @@ install: all
.PHONY: clean
clean:
$(RM) -f _*.h *.o *.so* *.a $(CLIENTS) $(DEPS)
+ $(RM) -f _*.c
# $(RM) -f $(AUTOSRCS) $(AUTOINCS)
distclean: clean
diff -r 5d51a404379e -r 6baa8ce2ec5e tools/libxl/gentypes.py
--- a/tools/libxl/gentypes.py Tue Aug 03 10:59:46 2010 +0100
+++ b/tools/libxl/gentypes.py Tue Aug 03 10:59:46 2010 +0100
@@ -58,13 +58,46 @@ 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, indent = " ", parent = ""):
+ s = ""
+ s += "// type: \"%s\"\n" % ty.typename
+ if isinstance(ty, libxltypes.KeyedUnion):
+ s += "// Keyed union with key %s%s\n" % (parent, ty.keyvar_name)
+ for f in ty.fields:
+ keyvar_expr = f.keyvar_expr % (parent + ty.keyvar_name)
+ s += "if (" + keyvar_expr + ") {\n"
+ s += " // Free %s\n" % (v + f.name)
+ s += libxl_C_type_destroy(f.type, v + f.name + ".", indent + "
", v)
+ s += "\n"
+ s += "}\n"
+ elif isinstance(ty, libxltypes.Aggregate):
+ for f in [f for f in ty.fields if f.type.has_destructor and not
f.const]:
+ if f.type.passbyref:
+ makeref = "&"
+ deref = "."
+ else:
+ makeref = ""
+ deref = "->"
+
+ if isinstance(f.type, libxltypes.Aggregate) and f.type.typename is
None:
+ s += libxl_C_type_destroy(f.type, v + f.name + ".", "", v)
+ s += "\n"
+ else:
+ s += "%s(%s%s%s);\n" % (f.type.destructor, makeref, v, f.name)
+ else:
+ raise NotImplementedError("%s" % type(ty))
+ s = s.rstrip("\n")
+ if s != "":
+ s = indent + s
+ return s.replace("\n", "\n%s" % indent)
+
if __name__ == '__main__':
- if len(sys.argv) < 2:
- print >>sys.stderr, "Usage: gentypes.py <header>"
+ if len(sys.argv) < 3:
+ print >>sys.stderr, "Usage: gentypes.py <header> <implementation>"
sys.exit(1)
header = sys.argv[1]
- print "outputting libxl types to %s" % header
+ print "outputting libxl type definitions to %s" % header
f = open(header, "w")
@@ -79,8 +112,45 @@ if __name__ == '__main__':
""" % " ".join(sys.argv))
- for t in libxltypes.Types:
- f.write(libxl_C_type_define(t) + ";\n")
+ for ty in libxltypes.Types:
+ f.write(libxl_C_type_define(ty) + ";\n")
+ if ty.has_destructor:
+ f.write("void %s(%s *p);\n" % (ty.destructor, ty.typename))
f.write("\n")
f.write("""#endif /* __LIBXL_TYPES_H */\n""")
+ f.close()
+
+ impl = sys.argv[2]
+ 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"
+
+static void __string_string_free(char **p)
+{
+
+}
+
+""" % " ".join(sys.argv))
+
+ for ty in [ty for ty in libxltypes.Types if ty.generated_destructor]:
+ f.write("void %s(%s *p)\n" % (ty.destructor, ty.typename))
+ f.write("{\n")
+ f.write(libxl_C_type_destroy(ty, "p->"))
+ f.write("\n")
+ f.write("}\n")
+ f.write("\n")
+ f.close()
diff -r 5d51a404379e -r 6baa8ce2ec5e tools/libxl/libxltypes.py
--- a/tools/libxl/libxltypes.py Tue Aug 03 10:59:46 2010 +0100
+++ b/tools/libxl/libxltypes.py Tue Aug 03 10:59:46 2010 +0100
@@ -2,6 +2,11 @@ class Type(object):
def __init__(self, typename, **kwargs):
self.comment = None
self.namespace = "libxl_"
+
+ self.has_destructor = True
+ self.generated_destructor = True
+
+ self.passbyref = False # passbyvalue
if kwargs.has_key('libxl_type'):
self.comment = kwargs['comment']
@@ -9,6 +14,21 @@ class Type(object):
if kwargs.has_key('namespace'):
self.namespace = kwargs['namespace']
+ if kwargs.has_key('has_destructor'):
+ self.has_destructor = kwargs['has_destructor']
+
+ if kwargs.has_key('passbyref'):
+ self.passbyref = kwargs['passbyref']
+
+ if not self.has_destructor:
+ self.generated_destructor = False
+
+ if kwargs.has_key('generated_destructor'):
+ self.generated_destructor = kwargs['generated_destructor']
+
+ if self.generated_destructor and not self.has_destructor:
+ raise Exception("Cannot generate no destructor!")
+
if typename is None: # Anonymous type
self.typename = None
elif self.namespace is None: # e.g. system provided types
@@ -16,22 +36,33 @@ class Type(object):
else:
self.typename = self.namespace + typename
+ if kwargs.has_key('destructor'):
+ self.destructor = kwargs['destructor']
+ elif self.typename is not None and self.has_destructor:
+ self.destructor = self.typename + "_destroy"
+ else:
+ self.destructor = None
+
class Builtin(Type):
"""Builtin type"""
- def __init__(self, typename, namespace = "libxl_"):
- Type.__init__(self, typename, namespace = namespace)
+ def __init__(self, typename, **kwargs):
+ if not kwargs.has_key("has_destructor"):
+ kwargs['has_destructor'] = False
+ if not kwargs.has_key("generate_destructor"):
+ kwargs['generate_destructor'] = False
+
+ Type.__init__(self, typename, **kwargs)
class UInt(Type):
def __init__(self, w):
typename = "uint%d_t" % w
- Type.__init__(self, typename, namespace = None)
+ Type.__init__(self, typename, namespace = None, has_destructor = False)
self.width = w
class BitField(Type):
def __init__(self, ty, w):
- Type.__init__(self, ty.typename, namespace = ty.namespace)
+ Type.__init__(self, ty.typename, namespace = ty.namespace,
has_destructor = False)
self.width = w
-
class Field(Type):
"""An element of an Aggregate type"""
@@ -45,11 +76,11 @@ class Field(Type):
class Aggregate(Type):
"""A type containing a collection of other types"""
- def __init__(self, kind, name, fields, comment = None):
- Type.__init__(self, name)
+ def __init__(self, kind, name, fields, comment = None, destructor = True):
+ Type.__init__(self, name, has_destructor = destructor,
generate_destructor = destructor, passbyref = True)
self.kind = kind
self.name = name
- self.comment = comment
+ self.comment = comment
self.fields = []
for f in fields:
# (name, type[, const=False[, comment=None]])
@@ -66,11 +97,11 @@ class Aggregate(Type):
class Struct(Aggregate):
def __init__(self, name, fields, comment = None):
- Aggregate.__init__(self, "struct", name, fields, comment)
+ Aggregate.__init__(self, "struct", name, fields, comment, True)
class Union(Aggregate):
def __init__(self, name, fields, comment = None):
- Aggregate.__init__(self, "union", name, fields, comment)
+ Aggregate.__init__(self, "union", name, fields, comment, False)
class KeyValueList(Type):
"""A map type"""
@@ -78,12 +109,12 @@ class KeyValueList(Type):
if ktype != string and vtype != string:
raise NotImplementedError("Only KeyValueList string -> string is
supported")
- Type.__init__(self, "char **", namespace = None)
+ Type.__init__(self, "char **", namespace = None, destructor =
"__string_string_free")
class KeyedUnion(Aggregate):
"""A union which is keyed of another variable"""
def __init__(self, name, keyvar_name, fields, comment = None):
- self.keyvar = keyvar_name
+ self.keyvar_name = keyvar_name
Aggregate.__init__(self, "union", name, [], comment)
for f in fields:
# (name, keyvar_expr, type)
@@ -97,7 +128,7 @@ class Reference(Type):
"""A reference to another type"""
def __init__(self, ty):
# Ugh
- Type.__init__(self, ty.name + " *")
+ Type.__init__(self, ty.name + " *", destructor = ty.destructor,
generated_destructor = False, passbyref = False)
#
# Standard Types
@@ -119,7 +150,7 @@ uint64 = UInt(64)
domid = UInt(32)
-string = Builtin("char *", namespace = None)
+string = Builtin("char *", namespace = None, has_destructor = True, destructor
= "free")
string_list = Builtin("char **", namespace = None)
inaddr_ip = Builtin("struct in_addr", namespace = None)
@@ -159,7 +190,9 @@ SHUTDOWN_* constant."""),
("vcpu_online", uint32),
])
-libxl_poolinfo = Struct("poolinfo", [("poolid", uint32)])
+libxl_poolinfo = Struct("poolinfo", [
+ ("poolid", uint32)
+ ])
libxl_vminfo = Struct("vminfo", [
("uuid", libxl_uuid),
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|