diff options
author | Ian Campbell <ian.campbell@citrix.com> | 2010-08-19 15:15:55 +0100 |
---|---|---|
committer | Ian Campbell <ian.campbell@citrix.com> | 2010-08-19 15:15:55 +0100 |
commit | 735f084c0f41c313c07bcd345f0abf2850e90c4e (patch) | |
tree | cd09ac22fbf4322a7159bc031b8729982333eee8 /tools/libxl/libxltypes.py | |
parent | 9d8fb61af7f770c9d72f9be506ad2c44b9c58794 (diff) | |
download | xen-735f084c0f41c313c07bcd345f0abf2850e90c4e.tar.gz xen-735f084c0f41c313c07bcd345f0abf2850e90c4e.tar.bz2 xen-735f084c0f41c313c07bcd345f0abf2850e90c4e.zip |
libxl: autogenerate _libxl_types.h
The libxl interface types are represented by a simple python data
structure (which could be parsed from a bespoke language in the
future).
This will allow the autogeneration of functions to free the component
members of the libxl types. In the future it may also enable auto
generation of type marshalling code for language bindings.
The generated file should be identical to before with the exception of
the "DO NOT EDIT" header.
It was unfortunately necessary to add explcit an dependency on
_libxl_types.h (indirectly via libxl.h) to all C files since the
autogenerated dependencies are not available in time.
[PATCH 04 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/libxltypes.py')
-rw-r--r-- | tools/libxl/libxltypes.py | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/tools/libxl/libxltypes.py b/tools/libxl/libxltypes.py new file mode 100644 index 0000000000..f08ee22c4b --- /dev/null +++ b/tools/libxl/libxltypes.py @@ -0,0 +1,168 @@ +import sys + +class Type(object): + def __init__(self, typename, **kwargs): + self.comment = kwargs.setdefault('comment', None) + self.namespace = kwargs.setdefault('namespace', "libxl_") + + if typename is None: # Anonymous type + self.typename = None + elif self.namespace is None: # e.g. system provided types + self.typename = typename + else: + self.typename = self.namespace + typename + +class Builtin(Type): + """Builtin type""" + def __init__(self, typename, **kwargs): + Type.__init__(self, typename, **kwargs) + +class UInt(Type): + def __init__(self, w, **kwargs): + kwargs.setdefault('namespace', None) + Type.__init__(self, "uint%d_t" % w, **kwargs) + + self.width = w + +class BitField(Type): + def __init__(self, ty, w, **kwargs): + kwargs.setdefault('namespace', None) + Type.__init__(self, ty.typename, **kwargs) + + self.width = w + +class Field(object): + """An element of an Aggregate type""" + def __init__(self, type, name, **kwargs): + self.type = type + self.name = name + self.const = kwargs.setdefault('const', False) + self.comment = kwargs.setdefault('comment', None) + self.keyvar_expr = kwargs.setdefault('keyvar_expr', None) + +class Aggregate(Type): + """A type containing a collection of other types""" + def __init__(self, kind, typename, fields, **kwargs): + Type.__init__(self, typename, **kwargs) + + self.kind = kind + + self.fields = [] + for f in fields: + # (name, type[, const=False[, comment=None]]) + if len(f) == 2: + n,t = f + const = False + comment = None + elif len(f) == 3: + n,t,const = f + comment = None + else: + n,t,const,comment = f + self.fields.append(Field(t,n,const=const,comment=comment)) + +class Struct(Aggregate): + def __init__(self, name, fields, **kwargs): + Aggregate.__init__(self, "struct", name, fields, **kwargs) + +class Union(Aggregate): + def __init__(self, name, fields, **kwargs): + Aggregate.__init__(self, "union", name, fields, **kwargs) + +class KeyedUnion(Aggregate): + """A union which is keyed of another variable in the parent structure""" + def __init__(self, name, keyvar_name, fields, **kwargs): + Aggregate.__init__(self, "union", name, [], **kwargs) + + self.keyvar_name = keyvar_name + + for f in fields: + # (name, keyvar_expr, type) + + # keyvar_expr must contain exactly one %s which will be replaced with the keyvar_name + + n, kve, ty = f + self.fields.append(Field(ty, n, keyvar_expr=kve)) + +class Reference(Type): + """A reference to another type""" + def __init__(self, ty, **kwargs): + # Ugh + kwargs.setdefault('namespace', ty.namespace) + typename = ty.typename[len(kwargs['namespace']):] + Type.__init__(self, typename + " *", **kwargs) + +# +# Standard Types +# + +void = Builtin("void *", namespace = None) +bool = Builtin("bool", namespace = None) +size_t = Builtin("size_t", namespace = None) + +integer = Builtin("int", namespace = None) +unsigned_integer = Builtin("unsigned int", namespace = None) +unsigned = Builtin("unsigned int", namespace = None) +unsigned_long = Builtin("unsigned long", namespace = None) + +uint8 = UInt(8) +uint16 = UInt(16) +uint32 = UInt(32) +uint64 = UInt(64) + +domid = UInt(32) + +string = Builtin("char *", namespace = None) + +inaddr_ip = Builtin("struct in_addr", namespace = None) + +class OrderedDict(dict): + """A dictionary which remembers insertion order. + + push to back on duplicate insertion""" + + def __init__(self): + dict.__init__(self) + self.__ordered = [] + + def __setitem__(self, key, value): + try: + self.__ordered.remove(key) + except ValueError: + pass + + self.__ordered.append(key) + dict.__setitem__(self, key, value) + + def ordered_keys(self): + return self.__ordered + def ordered_values(self): + return [self[x] for x in self.__ordered] + def ordered_items(self): + return [(x,self[x]) for x in self.__ordered] + +def parse(f): + print >>sys.stderr, "Parsing %s" % f + + globs = {} + locs = OrderedDict() + + for n,t in globals().items(): + if isinstance(t, Type): + globs[n] = t + elif isinstance(t,type(object)) and issubclass(t, Type): + globs[n] = t + + try: + execfile(f, globs, locs) + except SyntaxError,e: + raise SyntaxError, \ + "Errors were found at line %d while processing %s:\n\t%s"\ + %(e.lineno,f,e.text) + + types = [t for t in locs.ordered_values() if isinstance(t,Type)] + + builtins = [t for t in types if isinstance(t,Builtin)] + types = [t for t in types if not isinstance(t,Builtin)] + + return (builtins,types) |