# HG changeset patch
# User Ian Campbell <ian.campbell@xxxxxxxxxx>
# Date 1310997150 -3600
# Node ID 809882b6f1f84a5673d0ea18dfd392bb35774741
# Parent b373d7d341282c5a1761cc91a376a09b35572a1f
libxl: Keyed unions key off an enum instead of an arbitrary expression
Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
Acked-by: Ian Jackson <ian.jackson.citrix.com>
Committed-by: Ian Jackson <ian.jackson.citrix.com>
---
diff -r b373d7d34128 -r 809882b6f1f8 tools/libxl/gentypes.py
--- a/tools/libxl/gentypes.py Mon Jul 18 14:52:30 2011 +0100
+++ b/tools/libxl/gentypes.py Mon Jul 18 14:52:30 2011 +0100
@@ -81,12 +81,13 @@
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 -r b373d7d34128 -r 809882b6f1f8 tools/libxl/idl.txt
--- a/tools/libxl/idl.txt Mon Jul 18 14:52:30 2011 +0100
+++ b/tools/libxl/idl.txt Mon Jul 18 14:52:30 2011 +0100
@@ -127,13 +127,9 @@
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 -r b373d7d34128 -r 809882b6f1f8 tools/libxl/libxl.idl
--- a/tools/libxl/libxl.idl Mon Jul 18 14:52:30 2011 +0100
+++ b/tools/libxl/libxl.idl Mon Jul 18 14:52:30 2011 +0100
@@ -159,30 +159,28 @@
("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 -r b373d7d34128 -r 809882b6f1f8 tools/libxl/libxltypes.py
--- a/tools/libxl/libxltypes.py Mon Jul 18 14:52:30 2011 +0100
+++ b/tools/libxl/libxltypes.py Mon Jul 18 14:52:30 2011 +0100
@@ -116,6 +116,11 @@
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 @@
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 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
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|