$(LIBXL_OBJS) $(LIBXLU_OBJS) $(XL_OBJS): libxl.h
$(LIBXL_OBJS): libxl_internal.h
-_libxl_type%.h _libxl_type%_json.h _libxl_type%.c: libxl_type%.idl gentypes.py libxltypes.py
+_libxl_type%.h _libxl_type%_json.h _libxl_type%.c: libxl_type%.idl gentypes.py idl.py
$(PYTHON) gentypes.py libxl_type$*.idl __libxl_type$*.h __libxl_type$*_json.h __libxl_type$*.c
$(call move-if-changed,__libxl_type$*.h,_libxl_type$*.h)
$(call move-if-changed,__libxl_type$*_json.h,_libxl_type$*_json.h)
import re
import random
-import libxltypes
+import idl
def randomize_char(c):
if random.random() < 0.5:
def gen_rand_init(ty, v, indent = " ", parent = None):
s = ""
- if isinstance(ty, libxltypes.Enumeration):
+ if isinstance(ty, idl.Enumeration):
s += "%s = %s;\n" % (ty.pass_arg(v, parent is None), randomize_enum(ty))
- elif isinstance(ty, libxltypes.KeyedUnion):
+ elif isinstance(ty, idl.KeyedUnion):
if parent is None:
raise Exception("KeyedUnion type must have a parent")
s += "switch (%s) {\n" % (parent + ty.keyvar_name)
s += gen_rand_init(f.type, fexpr, indent + " ", nparent)
s += " break;\n"
s += "}\n"
- elif isinstance(ty, libxltypes.Struct) \
+ elif isinstance(ty, idl.Struct) \
and (parent is None or ty.json_fn is None):
for f in [f for f in ty.fields if not f.const]:
(nparent,fexpr) = ty.member(v, f, parent is None)
elif hasattr(ty, "rand_init") and ty.rand_init is not None:
s += "%s(%s);\n" % (ty.rand_init,
ty.pass_arg(v, isref=parent is None,
- passby=libxltypes.PASS_BY_REFERENCE))
+ passby=idl.PASS_BY_REFERENCE))
elif ty.typename in ["libxl_uuid", "libxl_mac", "libxl_hwcap"]:
s += "rand_bytes((uint8_t *)%s, sizeof(*%s));\n" % (v,v)
- elif ty.typename in ["libxl_domid"] or isinstance(ty, libxltypes.Number):
+ elif ty.typename in ["libxl_domid"] or isinstance(ty, idl.Number):
s += "%s = rand() %% (sizeof(%s)*8);\n" % \
(ty.pass_arg(v, parent is None),
ty.pass_arg(v, parent is None))
random.seed()
- idl = sys.argv[1]
- (builtins,types) = libxltypes.parse(idl)
+ (builtins,types) = idl.parse(sys.argv[1])
impl = sys.argv[2]
f = open(impl, "w")
if ty.typename not in handcoded:
f.write("static void %s_rand_init(%s);\n" % \
(ty.typename,
- ty.make_arg("p", passby=libxltypes.PASS_BY_REFERENCE)))
+ ty.make_arg("p", passby=idl.PASS_BY_REFERENCE)))
f.write("static void %s_rand_init(%s)\n" % \
(ty.typename,
- ty.make_arg("p", passby=libxltypes.PASS_BY_REFERENCE)))
+ ty.make_arg("p", passby=idl.PASS_BY_REFERENCE)))
f.write("{\n")
f.write(gen_rand_init(ty, "p"))
f.write("}\n")
for ty in [t for t in types if t.json_fn is not None]:
arg = ty.typename + "_val"
f.write(" %s_rand_init(%s);\n" % (ty.typename, \
- ty.pass_arg(arg, isref=False, passby=libxltypes.PASS_BY_REFERENCE)))
+ ty.pass_arg(arg, isref=False, passby=idl.PASS_BY_REFERENCE)))
f.write(" s = %s_to_json(ctx, %s);\n" % \
(ty.typename, ty.pass_arg(arg, isref=False)))
f.write(" printf(\"%%s: %%s\\n\", \"%s\", s);\n" % ty.typename)
f.write(" printf(\"Testing Enumerations\\n\");\n")
f.write(" printf(\"--------------------\\n\");\n")
f.write(" printf(\"\\n\");\n")
- for ty in [t for t in types if isinstance(t,libxltypes.Enumeration)]:
+ for ty in [t for t in types if isinstance(t,idl.Enumeration)]:
f.write(" printf(\"%s -- to string:\\n\");\n" % (ty.typename))
for v in ty.values:
f.write(" printf(\"\\t%s = %%d = \\\"%%s\\\"\\n\", " \
import sys
import re
-import libxltypes
+import idl
def libxl_C_instance_of(ty, instancename):
- if isinstance(ty, libxltypes.Aggregate) and ty.typename is None:
+ if isinstance(ty, idl.Aggregate) and ty.typename is None:
if instancename is None:
return libxl_C_type_define(ty)
else:
def libxl_C_type_define(ty, indent = ""):
s = ""
- if isinstance(ty, libxltypes.Enumeration):
+ if isinstance(ty, idl.Enumeration):
if ty.typename is None:
s += "enum {\n"
else:
else:
s += "} %s" % ty.typename
- elif isinstance(ty, libxltypes.Aggregate):
+ elif isinstance(ty, idl.Aggregate):
if ty.typename is None:
s += "%s {\n" % ty.kind
else:
def libxl_C_type_dispose(ty, v, indent = " ", parent = None):
s = ""
- if isinstance(ty, libxltypes.KeyedUnion):
+ if isinstance(ty, idl.KeyedUnion):
if parent is None:
raise Exception("KeyedUnion type must have a parent")
s += "switch (%s) {\n" % (parent + ty.keyvar_name)
s += libxl_C_type_dispose(f.type, fexpr, indent + " ", nparent)
s += " break;\n"
s += "}\n"
- elif isinstance(ty, libxltypes.Struct) and (parent is None or ty.dispose_fn is None):
+ elif isinstance(ty, idl.Struct) and (parent is None or ty.dispose_fn is None):
for f in [f for f in ty.fields if not f.const]:
(nparent,fexpr) = ty.member(v, f, parent is None)
s += libxl_C_type_dispose(f.type, fexpr, "", nparent)
s = ""
if parent is None:
s += "yajl_gen_status s;\n"
- if isinstance(ty, libxltypes.Enumeration):
+ if isinstance(ty, idl.Enumeration):
s += "s = libxl__yajl_gen_enum(hand, %s_to_string(%s));\n" % (ty.typename, ty.pass_arg(v, parent is None))
s += "if (s != yajl_gen_status_ok)\n"
s += " goto out;\n"
- elif isinstance(ty, libxltypes.KeyedUnion):
+ elif isinstance(ty, idl.KeyedUnion):
if parent is None:
raise Exception("KeyedUnion type must have a parent")
s += "switch (%s) {\n" % (parent + ty.keyvar_name)
s += libxl_C_type_gen_json(f.type, fexpr, indent + " ", nparent)
s += " break;\n"
s += "}\n"
- elif isinstance(ty, libxltypes.Struct) and (parent is None or ty.json_fn is None):
+ elif isinstance(ty, idl.Struct) and (parent is None or ty.json_fn is None):
s += "s = yajl_gen_map_open(hand);\n"
s += "if (s != yajl_gen_status_ok)\n"
s += " goto out;\n"
def libxl_C_type_to_json(ty, v, indent = " "):
s = ""
gen = "(libxl__gen_json_callback)&%s_gen_json" % ty.typename
- s += "return libxl__object_to_json(ctx, \"%s\", %s, (void *)%s);\n" % (ty.typename, gen, ty.pass_arg(v, passby=libxltypes.PASS_BY_REFERENCE))
+ s += "return libxl__object_to_json(ctx, \"%s\", %s, (void *)%s);\n" % (ty.typename, gen, ty.pass_arg(v, passby=idl.PASS_BY_REFERENCE))
if s != "":
s = indent + s
print >>sys.stderr, "Usage: gentypes.py <idl> <header> <header-json> <implementation>"
sys.exit(1)
- (_, idl, header, header_json, impl) = sys.argv
+ (_, idlname, header, header_json, impl) = sys.argv
- (builtins,types) = libxltypes.parse(idl)
+ (builtins,types) = idl.parse(idlname)
print "outputting libxl type definitions to %s" % header
f.write("void %s(%s);\n" % (ty.dispose_fn, ty.make_arg("p")))
if ty.json_fn is not None:
f.write("char *%s_to_json(libxl_ctx *ctx, %s);\n" % (ty.typename, ty.make_arg("p")))
- if isinstance(ty, libxltypes.Enumeration):
+ if isinstance(ty, idl.Enumeration):
f.write("const char *%s_to_string(%s);\n" % (ty.typename, ty.make_arg("p")))
- f.write("int %s_from_string(const char *s, %s);\n" % (ty.typename, ty.make_arg("e", passby=libxltypes.PASS_BY_REFERENCE)))
+ f.write("int %s_from_string(const char *s, %s);\n" % (ty.typename, ty.make_arg("e", passby=idl.PASS_BY_REFERENCE)))
f.write("extern libxl_enum_string_table %s_string_table[];\n" % (ty.typename))
f.write("\n")
""" % (header_json_define, header_json_define, " ".join(sys.argv)))
for ty in [ty for ty in types+builtins if ty.json_fn is not None]:
- f.write("yajl_gen_status %s_gen_json(yajl_gen hand, %s);\n" % (ty.typename, ty.make_arg("p", passby=libxltypes.PASS_BY_REFERENCE)))
+ f.write("yajl_gen_status %s_gen_json(yajl_gen hand, %s);\n" % (ty.typename, ty.make_arg("p", passby=idl.PASS_BY_REFERENCE)))
f.write("\n")
f.write("""#endif /* %s */\n""" % header_json_define)
f.write("}\n")
f.write("\n")
- for ty in [t for t in types if isinstance(t,libxltypes.Enumeration)]:
+ for ty in [t for t in types if isinstance(t,idl.Enumeration)]:
f.write("const char *%s_to_string(%s e)\n" % (ty.typename, ty.typename))
f.write("{\n")
f.write(libxl_C_enum_to_string(ty, "e"))
f.write("\n")
for ty in [t for t in types if t.json_fn is not None]:
- f.write("yajl_gen_status %s_gen_json(yajl_gen hand, %s)\n" % (ty.typename, ty.make_arg("p", passby=libxltypes.PASS_BY_REFERENCE)))
+ f.write("yajl_gen_status %s_gen_json(yajl_gen hand, %s)\n" % (ty.typename, ty.make_arg("p", passby=idl.PASS_BY_REFERENCE)))
f.write("{\n")
f.write(libxl_C_type_gen_json(ty, "p"))
f.write("}\n")
--- /dev/null
+import sys
+
+PASS_BY_VALUE = 1
+PASS_BY_REFERENCE = 2
+
+DIR_NONE = 0
+DIR_IN = 1
+DIR_OUT = 2
+DIR_BOTH = 3
+
+_default_namespace = ""
+def namespace(s):
+ if type(s) != str:
+ raise TypeError, "Require a string for the default namespace."
+ global _default_namespace
+ _default_namespace = s
+
+def _get_default_namespace():
+ global _default_namespace
+ return _default_namespace
+
+
+class Type(object):
+ def __init__(self, typename, **kwargs):
+ self.namespace = kwargs.setdefault('namespace',
+ _get_default_namespace())
+ self.dir = kwargs.setdefault('dir', DIR_BOTH)
+ if self.dir not in [DIR_NONE, DIR_IN, DIR_OUT, DIR_BOTH]:
+ raise ValueError
+
+ self.passby = kwargs.setdefault('passby', PASS_BY_VALUE)
+ if self.passby not in [PASS_BY_VALUE, PASS_BY_REFERENCE]:
+ raise ValueError
+
+ self.private = kwargs.setdefault('private', False)
+
+ if typename is None: # Anonymous type
+ self.typename = None
+ self.rawname = None
+ elif self.namespace is None: # e.g. system provided types
+ self.typename = typename
+ self.rawname = typename
+ else:
+ self.typename = self.namespace + typename
+ self.rawname = typename
+
+ if self.typename is not None:
+ self.dispose_fn = kwargs.setdefault('dispose_fn', self.typename + "_dispose")
+ else:
+ self.dispose_fn = kwargs.setdefault('dispose_fn', None)
+
+ self.autogenerate_dispose_fn = kwargs.setdefault('autogenerate_dispose_fn', True)
+
+ if self.typename is not None and not self.private:
+ self.json_fn = kwargs.setdefault('json_fn', self.typename + "_gen_json")
+ else:
+ self.json_fn = kwargs.setdefault('json_fn', None)
+
+ self.autogenerate_json = kwargs.setdefault('autogenerate_json', True)
+
+ def marshal_in(self):
+ return self.dir in [DIR_IN, DIR_BOTH]
+ def marshal_out(self):
+ return self.dir in [DIR_OUT, DIR_BOTH]
+
+ def make_arg(self, n, passby=None):
+ if passby is None: passby = self.passby
+
+ if passby == PASS_BY_REFERENCE:
+ return "%s *%s" % (self.typename, n)
+ else:
+ return "%s %s" % (self.typename, n)
+
+ def pass_arg(self, n, isref=None, passby=None):
+ if passby is None: passby = self.passby
+ if isref is None: isref = self.passby == PASS_BY_REFERENCE
+
+ if passby == PASS_BY_REFERENCE:
+ if isref:
+ return "%s" % (n)
+ else:
+ return "&%s" % (n)
+ else:
+ if isref:
+ return "*%s" % (n)
+ else:
+ return "%s" % (n)
+
+class Builtin(Type):
+ """Builtin type"""
+ def __init__(self, typename, **kwargs):
+ kwargs.setdefault('dispose_fn', None)
+ kwargs.setdefault('autogenerate_dispose_fn', False)
+ kwargs.setdefault('autogenerate_json', False)
+ Type.__init__(self, typename, **kwargs)
+
+class Number(Builtin):
+ def __init__(self, ctype, **kwargs):
+ kwargs.setdefault('namespace', None)
+ kwargs.setdefault('dispose_fn', None)
+ kwargs.setdefault('signed', False)
+ kwargs.setdefault('json_fn', "yajl_gen_integer")
+ self.signed = kwargs['signed']
+ Builtin.__init__(self, ctype, **kwargs)
+
+class UInt(Number):
+ def __init__(self, w, **kwargs):
+ kwargs.setdefault('namespace', None)
+ kwargs.setdefault('dispose_fn', None)
+ Number.__init__(self, "uint%d_t" % w, **kwargs)
+
+ self.width = w
+
+class EnumerationValue(object):
+ def __init__(self, enum, value, name, **kwargs):
+ self.enum = enum
+
+ self.valuename = str.upper(name)
+ self.rawname = str.upper(enum.rawname) + "_" + self.valuename
+ self.name = str.upper(enum.namespace) + self.rawname
+ self.value = value
+
+class Enumeration(Type):
+ def __init__(self, typename, values, **kwargs):
+ kwargs.setdefault('dispose_fn', None)
+ Type.__init__(self, typename, **kwargs)
+
+ self.values = []
+ for v in values:
+ # (value, name)
+ (num,name) = v
+ self.values.append(EnumerationValue(self, num, name,
+ typename=self.rawname))
+ def lookup(self, name):
+ for v in self.values:
+ if v.valuename == str.upper(name):
+ return v
+ return ValueError
+
+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.enumname = kwargs.setdefault('enumname', 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[, {kw args}])
+ if len(f) == 2:
+ n,t = f
+ kw = {}
+ elif len(f) == 3:
+ n,t,kw = f
+ else:
+ raise ValueError
+ if n is None:
+ raise ValueError
+ self.fields.append(Field(t,n,**kw))
+
+ # Returns a tuple (stem, field-expr)
+ #
+ # field-expr is a C expression for a field "f" within the struct
+ # "v".
+ #
+ # stem is the stem common to both "f" and any other sibbling field
+ # within the "v".
+ def member(self, v, f, isref):
+ if isref:
+ deref = v + "->"
+ else:
+ deref = v + "."
+
+ if f.name is None: # Anonymous
+ return (deref, deref)
+ else:
+ return (deref, deref + f.name)
+
+class Struct(Aggregate):
+ def __init__(self, name, fields, **kwargs):
+ kwargs.setdefault('passby', PASS_BY_REFERENCE)
+ Aggregate.__init__(self, "struct", name, fields, **kwargs)
+
+class Union(Aggregate):
+ def __init__(self, name, fields, **kwargs):
+ # Generally speaking some intelligence is required to free a
+ # union therefore any specific instance of this class will
+ # need to provide an explicit destructor function.
+ kwargs.setdefault('passby', PASS_BY_REFERENCE)
+ kwargs.setdefault('dispose_fn', None)
+ 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_type, keyvar_name, fields, **kwargs):
+ Aggregate.__init__(self, "union", name, [], **kwargs)
+
+ if not isinstance(keyvar_type, Enumeration):
+ raise ValueError
+
+ self.keyvar_name = keyvar_name
+ self.keyvar_type = keyvar_type
+
+ for f in fields:
+ # (name, enum, type)
+ e, ty = f
+ ev = keyvar_type.lookup(e)
+ en = ev.name
+ self.fields.append(Field(ty, e, enumname=en))
+
+#
+# Standard Types
+#
+
+void = Builtin("void *", namespace = None)
+bool = Builtin("bool", namespace = None,
+ json_fn = "yajl_gen_bool",
+ autogenerate_json = False)
+
+size_t = Number("size_t", namespace = None)
+
+integer = Number("int", namespace = None, signed = True)
+
+uint8 = UInt(8)
+uint16 = UInt(16)
+uint32 = UInt(32)
+uint64 = UInt(64)
+
+string = Builtin("char *", namespace = None, dispose_fn = "free",
+ json_fn = "libxl__string_gen_json",
+ autogenerate_json = False)
+
+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
+ elif n in ['PASS_BY_REFERENCE', 'PASS_BY_VALUE',
+ 'DIR_NONE', 'DIR_IN', 'DIR_OUT', 'DIR_BOTH',
+ 'namespace']:
+ 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)
-libxltypes IDL
---------------
+libxl IDL
+---------
Each type in the libxl interface is represented by an object of type
-libxltypes.Type (or a subclass thereof). Every local variable defined
-by the .idl file must be an instance of libxltypes.Type (e.g. you may
-not define Python functions or any other construct other than defining
+idl.Type (or a subclass thereof). Every local variable defined by
+the .idl file must be an instance of idl.Type (e.g. you may not
+define Python functions or any other construct other than defining
variables)
The name of the type must be passed as the first argument to the
namespace element while Type.rawname is always set to the 'base' name
of the type.
-The libxltypes.Type base class has several other properties which
-apply to all types. The properties are set by passing a named
-parameter to the constructor.
+The idl.Type base class has several other properties which apply
+to all types. The properties are set by passing a named parameter to
+the constructor.
Type.namespace: (default: "libxl_")
If the typename is not None then the namespace is prepended to the
type.
-Type.passby: (default: libxltypes.PASS_BY_VALUE)
+Type.passby: (default: idl.PASS_BY_VALUE)
Defines the manner in which a type should be passed to C
functions. Valid values for this fields are:
- libxltypes.PASS_BY_VALUE
- libxltypes.PASS_BY_REFERENCE
+ idl.PASS_BY_VALUE
+ idl.PASS_BY_REFERENCE
Type.dispose_fn: (default: typename + "_dispose" or None if type == None)
Other simple type-Classes
-------------------------
-libxltype.Builtin
+idl.Builtin
Instances of this class represent types which are predefined within
the system.
-libxltype.UInt
+idl.UInt
Instances of this class represent the standard uint<N>_t types.
Complex type-Classes
--------------------
-libxltype.Enumeration
+idl.Enumeration
A class representing an enumeration (named integer values).
The values are available in the list Enumeration.values. Each
- element in the list is of type libxltype.EnumerationValue.
+ element in the list is of type idl.EnumerationValue.
Each EnumerationValue has the following properties:
and any namespace (e.g. "VALUE")
EnumerationValue.value The integer value associated with this name.
-libxltype.Aggregate
+idl.Aggregate
Base class for type-Classes which contain a number of other types
(e.g. structs and unions).
The contained types are available in the list Aggregate.fields. Each
- element in the list is of type libxltype.Field representing a member
- of the aggregate.
+ element in the list is of type idl.Field representing a member of the
+ aggregate.
Each field has the following properties:
- Field.type The type of the member (a libxltypes.Type).
+ Field.type The type of the member (a idl.Type).
Field.name The name of the member (can be None for anonymous
fields).
Field.const Boolean, true if the member is const.
-libxltype.Struct
+idl.Struct
- A subclass of libxltype.Aggregate representing the C struct type.
+ A subclass of idl.Aggregate representing the C struct type.
Struct.kind == "struct"
-libxltype.Union
+idl.Union
- A subclass of libxltype.Aggregate representing the C union type.
+ A subclass of idl.Aggregate representing the C union type.
Union.kind == "union"
-libxltype.KeyedUnion
+idl.KeyedUnion
- A subclass of libxltype.Aggregate which represents the C union type
+ A subclass of idl.Aggregate which represents the C union type
where the currently valid member of the union can be determined based
upon another member in the containing type.
+++ /dev/null
-import sys
-
-PASS_BY_VALUE = 1
-PASS_BY_REFERENCE = 2
-
-DIR_NONE = 0
-DIR_IN = 1
-DIR_OUT = 2
-DIR_BOTH = 3
-
-_default_namespace = ""
-def namespace(s):
- if type(s) != str:
- raise TypeError, "Require a string for the default namespace."
- global _default_namespace
- _default_namespace = s
-
-def _get_default_namespace():
- global _default_namespace
- return _default_namespace
-
-
-class Type(object):
- def __init__(self, typename, **kwargs):
- self.namespace = kwargs.setdefault('namespace',
- _get_default_namespace())
- self.dir = kwargs.setdefault('dir', DIR_BOTH)
- if self.dir not in [DIR_NONE, DIR_IN, DIR_OUT, DIR_BOTH]:
- raise ValueError
-
- self.passby = kwargs.setdefault('passby', PASS_BY_VALUE)
- if self.passby not in [PASS_BY_VALUE, PASS_BY_REFERENCE]:
- raise ValueError
-
- self.private = kwargs.setdefault('private', False)
-
- if typename is None: # Anonymous type
- self.typename = None
- self.rawname = None
- elif self.namespace is None: # e.g. system provided types
- self.typename = typename
- self.rawname = typename
- else:
- self.typename = self.namespace + typename
- self.rawname = typename
-
- if self.typename is not None:
- self.dispose_fn = kwargs.setdefault('dispose_fn', self.typename + "_dispose")
- else:
- self.dispose_fn = kwargs.setdefault('dispose_fn', None)
-
- self.autogenerate_dispose_fn = kwargs.setdefault('autogenerate_dispose_fn', True)
-
- if self.typename is not None and not self.private:
- self.json_fn = kwargs.setdefault('json_fn', self.typename + "_gen_json")
- else:
- self.json_fn = kwargs.setdefault('json_fn', None)
-
- self.autogenerate_json = kwargs.setdefault('autogenerate_json', True)
-
- def marshal_in(self):
- return self.dir in [DIR_IN, DIR_BOTH]
- def marshal_out(self):
- return self.dir in [DIR_OUT, DIR_BOTH]
-
- def make_arg(self, n, passby=None):
- if passby is None: passby = self.passby
-
- if passby == PASS_BY_REFERENCE:
- return "%s *%s" % (self.typename, n)
- else:
- return "%s %s" % (self.typename, n)
-
- def pass_arg(self, n, isref=None, passby=None):
- if passby is None: passby = self.passby
- if isref is None: isref = self.passby == PASS_BY_REFERENCE
-
- if passby == PASS_BY_REFERENCE:
- if isref:
- return "%s" % (n)
- else:
- return "&%s" % (n)
- else:
- if isref:
- return "*%s" % (n)
- else:
- return "%s" % (n)
-
-class Builtin(Type):
- """Builtin type"""
- def __init__(self, typename, **kwargs):
- kwargs.setdefault('dispose_fn', None)
- kwargs.setdefault('autogenerate_dispose_fn', False)
- kwargs.setdefault('autogenerate_json', False)
- Type.__init__(self, typename, **kwargs)
-
-class Number(Builtin):
- def __init__(self, ctype, **kwargs):
- kwargs.setdefault('namespace', None)
- kwargs.setdefault('dispose_fn', None)
- kwargs.setdefault('signed', False)
- kwargs.setdefault('json_fn', "yajl_gen_integer")
- self.signed = kwargs['signed']
- Builtin.__init__(self, ctype, **kwargs)
-
-class UInt(Number):
- def __init__(self, w, **kwargs):
- kwargs.setdefault('namespace', None)
- kwargs.setdefault('dispose_fn', None)
- Number.__init__(self, "uint%d_t" % w, **kwargs)
-
- self.width = w
-
-class EnumerationValue(object):
- def __init__(self, enum, value, name, **kwargs):
- self.enum = enum
-
- self.valuename = str.upper(name)
- self.rawname = str.upper(enum.rawname) + "_" + self.valuename
- self.name = str.upper(enum.namespace) + self.rawname
- self.value = value
-
-class Enumeration(Type):
- def __init__(self, typename, values, **kwargs):
- kwargs.setdefault('dispose_fn', None)
- Type.__init__(self, typename, **kwargs)
-
- self.values = []
- for v in values:
- # (value, name)
- (num,name) = v
- self.values.append(EnumerationValue(self, num, name,
- typename=self.rawname))
- def lookup(self, name):
- for v in self.values:
- if v.valuename == str.upper(name):
- return v
- return ValueError
-
-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.enumname = kwargs.setdefault('enumname', 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[, {kw args}])
- if len(f) == 2:
- n,t = f
- kw = {}
- elif len(f) == 3:
- n,t,kw = f
- else:
- raise ValueError
- if n is None:
- raise ValueError
- self.fields.append(Field(t,n,**kw))
-
- # Returns a tuple (stem, field-expr)
- #
- # field-expr is a C expression for a field "f" within the struct
- # "v".
- #
- # stem is the stem common to both "f" and any other sibbling field
- # within the "v".
- def member(self, v, f, isref):
- if isref:
- deref = v + "->"
- else:
- deref = v + "."
-
- if f.name is None: # Anonymous
- return (deref, deref)
- else:
- return (deref, deref + f.name)
-
-class Struct(Aggregate):
- def __init__(self, name, fields, **kwargs):
- kwargs.setdefault('passby', PASS_BY_REFERENCE)
- Aggregate.__init__(self, "struct", name, fields, **kwargs)
-
-class Union(Aggregate):
- def __init__(self, name, fields, **kwargs):
- # Generally speaking some intelligence is required to free a
- # union therefore any specific instance of this class will
- # need to provide an explicit destructor function.
- kwargs.setdefault('passby', PASS_BY_REFERENCE)
- kwargs.setdefault('dispose_fn', None)
- 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_type, keyvar_name, fields, **kwargs):
- Aggregate.__init__(self, "union", name, [], **kwargs)
-
- if not isinstance(keyvar_type, Enumeration):
- raise ValueError
-
- self.keyvar_name = keyvar_name
- self.keyvar_type = keyvar_type
-
- for f in fields:
- # (name, enum, type)
- e, ty = f
- ev = keyvar_type.lookup(e)
- en = ev.name
- self.fields.append(Field(ty, e, enumname=en))
-
-#
-# Standard Types
-#
-
-void = Builtin("void *", namespace = None)
-bool = Builtin("bool", namespace = None,
- json_fn = "yajl_gen_bool",
- autogenerate_json = False)
-
-size_t = Number("size_t", namespace = None)
-
-integer = Number("int", namespace = None, signed = True)
-
-uint8 = UInt(8)
-uint16 = UInt(16)
-uint32 = UInt(32)
-uint64 = UInt(64)
-
-string = Builtin("char *", namespace = None, dispose_fn = "free",
- json_fn = "libxl__string_gen_json",
- autogenerate_json = False)
-
-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
- elif n in ['PASS_BY_REFERENCE', 'PASS_BY_VALUE',
- 'DIR_NONE', 'DIR_IN', 'DIR_OUT', 'DIR_BOTH',
- 'namespace']:
- 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)
$(Q)mv xenlight.mli.tmp xenlight.mli
_libxl_types.ml.in _libxl_types.mli.in _libxl_types.inc: genwrap.py $(XEN_ROOT)/tools/libxl/libxl_types.idl \
- $(XEN_ROOT)/tools/libxl/libxltypes.py
+ $(XEN_ROOT)/tools/libxl/idl.py
PYTHONPATH=$(XEN_ROOT)/tools/libxl $(PYTHON) genwrap.py \
$(XEN_ROOT)/tools/libxl/libxl_types.idl \
_libxl_types.mli.in _libxl_types.ml.in _libxl_types.inc
import sys,os
-import libxltypes
+import idl
# typename -> ( ocaml_type, c_from_ocaml, ocaml_from_c )
builtins = {
def ocaml_type_of(ty):
if ty.rawname == "domid":
return "domid"
- elif isinstance(ty,libxltypes.UInt):
+ elif isinstance(ty,idl.UInt):
if ty.width in [8, 16]:
# handle as ints
width = None
else:
return "int"
- elif isinstance(ty,libxltypes.Builtin):
+ elif isinstance(ty,idl.Builtin):
if not builtins.has_key(ty.typename):
raise NotImplementedError("Unknown Builtin %s (%s)" % (ty.typename, type(ty)))
typename,_,_ = builtins[ty.typename]
if not typename:
raise NotImplementedError("No typename for Builtin %s (%s)" % (ty.typename, type(ty)))
return typename
- elif isinstance(ty,libxltypes.Aggregate):
+ elif isinstance(ty,idl.Aggregate):
return ty.rawname.capitalize() + ".t"
else:
return ty.rawname
s = ("""(* %s interface *)\n""" % ty.typename)
else:
s = ("""(* %s implementation *)\n""" % ty.typename)
- if isinstance(ty, libxltypes.Enumeration):
+ if isinstance(ty, idl.Enumeration):
s = "type %s = \n" % ty.rawname
for v in ty.values:
s += "\t | %s\n" % v.rawname
- elif isinstance(ty, libxltypes.Aggregate):
+ elif isinstance(ty, idl.Aggregate):
s = ""
if ty.typename is None:
raise NotImplementedError("%s has no typename" % type(ty))
def c_val(ty, c, o, indent="", parent = None):
s = indent
- if isinstance(ty,libxltypes.UInt):
+ if isinstance(ty,idl.UInt):
if ty.width in [8, 16]:
# handle as ints
width = None
s += "%s = Int%d_val(%s);" % (c, width, o)
else:
s += "%s = Int_val(%s);" % (c, o)
- elif isinstance(ty,libxltypes.Builtin):
+ elif isinstance(ty,idl.Builtin):
if not builtins.has_key(ty.typename):
raise NotImplementedError("Unknown Builtin %s (%s)" % (ty.typename, type(ty)))
_,fn,_ = builtins[ty.typename]
if not fn:
raise NotImplementedError("No c_val fn for Builtin %s (%s)" % (ty.typename, type(ty)))
s += "%s;" % (fn % { "o": o, "c": c })
- elif isinstance(ty,libxltypes.Enumeration) and (parent is None):
+ elif isinstance(ty,idl.Enumeration) and (parent is None):
n = 0
s += "switch(Int_val(%s)) {\n" % o
for e in ty.values:
n += 1
s += " default: failwith_xl(\"cannot convert value to %s\", lg); break;\n" % ty.typename
s += "}"
- elif isinstance(ty, libxltypes.Aggregate) and (parent is None):
+ elif isinstance(ty, idl.Aggregate) and (parent is None):
n = 0
for f in ty.fields:
if f.type.private:
s += "%s\n" % c_val(f.type, fexpr, "Field(%s, %d)" % (o,n), parent=nparent)
n = n + 1
else:
- s += "%s_val(gc, lg, %s, %s);" % (ty.rawname, ty.pass_arg(c, parent is None, passby=libxltypes.PASS_BY_REFERENCE), o)
+ s += "%s_val(gc, lg, %s, %s);" % (ty.rawname, ty.pass_arg(c, parent is None, passby=idl.PASS_BY_REFERENCE), o)
return s.replace("\n", "\n%s" % indent)
def gen_c_val(ty, indent=""):
s = "/* Convert caml value to %s */\n" % ty.rawname
- s += "static int %s_val (caml_gc *gc, struct caml_logger *lg, %s, value v)\n" % (ty.rawname, ty.make_arg("c_val", passby=libxltypes.PASS_BY_REFERENCE))
+ s += "static int %s_val (caml_gc *gc, struct caml_logger *lg, %s, value v)\n" % (ty.rawname, ty.make_arg("c_val", passby=idl.PASS_BY_REFERENCE))
s += "{\n"
s += "\tCAMLparam1(v);\n"
s += "\n"
def ocaml_Val(ty, o, c, indent="", parent = None):
s = indent
- if isinstance(ty,libxltypes.UInt):
+ if isinstance(ty,idl.UInt):
if ty.width in [8, 16]:
# handle as ints
width = None
s += "%s = caml_copy_int%d(%s);" % (o, width, c)
else:
s += "%s = Val_int(%s);" % (o, c)
- elif isinstance(ty,libxltypes.Builtin):
+ elif isinstance(ty,idl.Builtin):
if not builtins.has_key(ty.typename):
raise NotImplementedError("Unknown Builtin %s (%s)" % (ty.typename, type(ty)))
_,_,fn = builtins[ty.typename]
if not fn:
raise NotImplementedError("No ocaml Val fn for Builtin %s (%s)" % (ty.typename, type(ty)))
s += "%s = %s;" % (o, fn % { "c": c })
- elif isinstance(ty,libxltypes.Enumeration) and (parent is None):
+ elif isinstance(ty,idl.Enumeration) and (parent is None):
n = 0
s += "switch(%s) {\n" % c
for e in ty.values:
n += 1
s += " default: failwith_xl(\"cannot convert value from %s\", lg); break;\n" % ty.typename
s += "}"
- elif isinstance(ty,libxltypes.Aggregate) and (parent is None):
+ elif isinstance(ty,idl.Aggregate) and (parent is None):
s += "{\n"
s += "\tvalue %s_field;\n" % ty.rawname
s += "\n"
print >>sys.stderr, "Usage: genwrap.py <idl> <mli> <ml> <c-inc>"
sys.exit(1)
- idl = sys.argv[1]
- (_,types) = libxltypes.parse(idl)
+ (_,types) = idl.parse(sys.argv[1])
# Do not generate these yet.
blacklist = [
.PHONY: build
build: genpath genwrap.py $(XEN_ROOT)/tools/libxl/libxl_types.idl \
- $(XEN_ROOT)/tools/libxl/libxltypes.py
+ $(XEN_ROOT)/tools/libxl/idl.py
PYTHONPATH=$(XEN_ROOT)/tools/libxl $(PYTHON) genwrap.py \
$(XEN_ROOT)/tools/libxl/libxl_types.idl \
xen/lowlevel/xl/_pyxl_types.h \
import sys,os
-import libxltypes
+import idl
(TYPE_BOOL, TYPE_INT, TYPE_UINT, TYPE_STRING, TYPE_AGGREGATE) = range(5)
def py_type(ty):
- if ty == libxltypes.bool:
+ if ty == idl.bool:
return TYPE_BOOL
- if isinstance(ty, libxltypes.Enumeration):
+ if isinstance(ty, idl.Enumeration):
return TYPE_UINT
- if isinstance(ty, libxltypes.Number):
+ if isinstance(ty, idl.Number):
if ty.signed:
return TYPE_INT
else:
return TYPE_UINT
- if isinstance(ty, libxltypes.Aggregate):
+ if isinstance(ty, idl.Aggregate):
return TYPE_AGGREGATE
- if ty == libxltypes.string:
+ if ty == idl.string:
return TYPE_STRING
return None
def py_decls(ty):
l = []
- if isinstance(ty, libxltypes.Aggregate):
+ if isinstance(ty, idl.Aggregate):
l.append('_hidden Py_%s *Py%s_New(void);\n'%(ty.rawname, ty.rawname))
l.append('_hidden int Py%s_Check(PyObject *self);\n'%ty.rawname)
for f in ty.fields:
l.append('void genwrap__init(PyObject *m)')
l.append('{')
for ty in types:
- if isinstance(ty, libxltypes.Enumeration):
+ if isinstance(ty, idl.Enumeration):
for v in ty.values:
l.append(' PyModule_AddIntConstant(m, "%s", %s);' % (v.rawname, v.name))
- elif isinstance(ty, libxltypes.Aggregate):
+ elif isinstance(ty, idl.Aggregate):
l.append(' if (PyType_Ready(&Py%s_Type) >= 0) {'%ty.rawname)
l.append(' Py_INCREF(&Py%s_Type);'%ty.rawname)
l.append(' PyModule_AddObject(m, "%s", (PyObject *)&Py%s_Type);'%(ty.rawname, ty.rawname))
def tree_frob(types):
ret = types[:]
- for ty in [ty for ty in ret if isinstance(ty, libxltypes.Aggregate)]:
+ for ty in [ty for ty in ret if isinstance(ty, idl.Aggregate)]:
ty.fields = filter(lambda f:f.name is not None and f.type.typename is not None, ty.fields)
return ret
print >>sys.stderr, "Usage: genwrap.py <idl> <decls> <defns>"
sys.exit(1)
- idl = sys.argv[1]
- (_,types) = libxltypes.parse(idl)
+ (_,types) = idl.parse(sys.argv[1])
types = tree_frob(types)
_hidden int genwrap__ll_set(PyObject *v, long long *val, long long mask);
""" % " ".join(sys.argv))
- for ty in [ty for ty in types if isinstance(ty, libxltypes.Aggregate)]:
+ for ty in [ty for ty in types if isinstance(ty, idl.Aggregate)]:
f.write('/* Internal API for %s wrapper */\n'%ty.typename)
f.write(py_wrapstruct(ty))
f.write(py_decls(ty))
for ty in types:
if ty.private:
continue
- if isinstance(ty, libxltypes.Aggregate):
+ if isinstance(ty, idl.Aggregate):
f.write('/* Attribute get/set functions for %s */\n'%ty.typename)
for a in ty.fields:
if a.type.private: