aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/libxl/gentypes.py7
-rw-r--r--tools/libxl/idl.txt10
-rw-r--r--tools/libxl/libxl.idl46
-rw-r--r--tools/libxl/libxltypes.py24
4 files changed, 45 insertions, 42 deletions
diff --git a/tools/libxl/gentypes.py b/tools/libxl/gentypes.py
index 120c6d357e..23406fceac 100644
--- a/tools/libxl/gentypes.py
+++ b/tools/libxl/gentypes.py
@@ -81,12 +81,13 @@ def libxl_C_type_destroy(ty, v, indent = " ", parent = None):
if isinstance(ty, libxltypes.KeyedUnion):
if parent is None:
raise Exception("KeyedUnion type must have a parent")
+ s += "switch (%s) {\n" % (parent + ty.keyvar_name)
for f in ty.fields:
(nparent,fexpr) = ty.member(v, f, parent is None)
- keyvar_expr = f.keyvar_expr % (parent + ty.keyvar_name)
- s += "if (" + keyvar_expr + ") {\n"
+ s += "case %s:\n" % f.enumname
s += libxl_C_type_destroy(f.type, fexpr, indent + " ", nparent)
- s += "}\n"
+ s += " break;\n"
+ s += "}\n"
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]:
(nparent,fexpr) = ty.member(v, f, parent is None)
diff --git a/tools/libxl/idl.txt b/tools/libxl/idl.txt
index dad59ac50c..271a2a8900 100644
--- a/tools/libxl/idl.txt
+++ b/tools/libxl/idl.txt
@@ -127,13 +127,9 @@ libxltype.KeyedUnion
upon another member in the containing type.
The KeyedUnion.keyvar_name must contain the name of the member of the
- containing type which determines the valid member of the union
-
- The fields in a KeyedUnion have an extra Field.keyvar_expr
- property. This must be a string containing a single "%s" format
- specifier such that when "%s" is substited by an instance of
- KeyedUnion.keyvar_name it becomes a C expression which evaluates to
- True IFF this field currently contains valid data.
+ containing type which determines the valid member of the union. The
+ member referenced by KeyedUnion.keyvar_name has type
+ KeyedUnion.keyvar_type which must be an instance of the Enumeration type.
Standard Types
--------------
diff --git a/tools/libxl/libxl.idl b/tools/libxl/libxl.idl
index 7f99f556f4..f169c2c129 100644
--- a/tools/libxl/libxl.idl
+++ b/tools/libxl/libxl.idl
@@ -159,30 +159,28 @@ libxl_domain_build_info = Struct("domain_build_info",[
("disable_migrate", bool),
("cpuid", libxl_cpuid_policy_list),
("type", libxl_domain_type),
- ("u", KeyedUnion(None, "type",
- [("hvm", "%s == LIBXL_DOMAIN_TYPE_HVM", Struct(None,
- [("firmware", string),
- ("pae", bool),
- ("apic", bool),
- ("acpi", bool),
- ("nx", bool),
- ("viridian", bool),
- ("timeoffset", string),
- ("hpet", bool),
- ("vpt_align", bool),
- ("timer_mode", integer),
- ("nested_hvm", bool),
- ])),
- ("pv", "%s == LIBXL_DOMAIN_TYPE_PV", Struct(None,
- [("kernel", libxl_file_reference),
- ("slack_memkb", uint32),
- ("bootloader", string),
- ("bootloader_args", string),
- ("cmdline", string),
- ("ramdisk", libxl_file_reference),
- ("features", string, True),
- ("e820_host", bool, False, "Use host's E820 for PCI passthrough."),
- ])),
+ ("u", KeyedUnion(None, libxl_domain_type, "type",
+ [("hvm", Struct(None, [("firmware", string),
+ ("pae", bool),
+ ("apic", bool),
+ ("acpi", bool),
+ ("nx", bool),
+ ("viridian", bool),
+ ("timeoffset", string),
+ ("hpet", bool),
+ ("vpt_align", bool),
+ ("timer_mode", integer),
+ ("nested_hvm", bool),
+ ])),
+ ("pv", Struct(None, [("kernel", libxl_file_reference),
+ ("slack_memkb", uint32),
+ ("bootloader", string),
+ ("bootloader_args", string),
+ ("cmdline", string),
+ ("ramdisk", libxl_file_reference),
+ ("features", string, True),
+ ("e820_host", bool, False, "Use host's E820 for PCI passthrough."),
+ ])),
])),
],
comment =
diff --git a/tools/libxl/libxltypes.py b/tools/libxl/libxltypes.py
index b7b46697db..481e0d593e 100644
--- a/tools/libxl/libxltypes.py
+++ b/tools/libxl/libxltypes.py
@@ -116,6 +116,11 @@ class Enumeration(Type):
self.values.append(EnumerationValue(self, num, name,
comment=comment,
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"""
@@ -124,7 +129,7 @@ class Field(object):
self.name = name
self.const = kwargs.setdefault('const', False)
self.comment = kwargs.setdefault('comment', None)
- self.keyvar_expr = kwargs.setdefault('keyvar_expr', None)
+ self.enumname = kwargs.setdefault('enumname', None)
class Aggregate(Type):
"""A type containing a collection of other types"""
@@ -181,18 +186,21 @@ class Union(Aggregate):
class KeyedUnion(Aggregate):
"""A union which is keyed of another variable in the parent structure"""
- def __init__(self, name, keyvar_name, fields, **kwargs):
+ 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, 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))
+ # (name, enum, type)
+ e, ty = f
+ ev = keyvar_type.lookup(e)
+ en = ev.name
+ self.fields.append(Field(ty, e, enumname=en))
#
# Standard Types