# HG changeset patch
# User Ian Campbell <ian.campbell@xxxxxxxxxx>
# Date 1310979574 -3600
# Node ID cf2f4b79c21f5a1b72b59f5da2f644b6d704b51e
# Parent 6bd6decb4f8760cc5f2fb47fef27de522fbc8c8a
libxl: Keyed unions key off an enum instead of an arbitrary expression
Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
diff -r 6bd6decb4f87 -r cf2f4b79c21f tools/libxl/gentest.py
--- a/tools/libxl/gentest.py Mon Jul 18 09:59:33 2011 +0100
+++ b/tools/libxl/gentest.py Mon Jul 18 09:59:34 2011 +0100
@@ -30,12 +30,13 @@ def gen_rand_init(ty, v, indent = " "
elif 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 += gen_rand_init(f.type, fexpr, indent + " ", nparent)
- s += "}\n"
+ s += " break;\n"
+ s += "}\n"
elif isinstance(ty, libxltypes.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)
diff -r 6bd6decb4f87 -r cf2f4b79c21f tools/libxl/gentypes.py
--- a/tools/libxl/gentypes.py Mon Jul 18 09:59:33 2011 +0100
+++ b/tools/libxl/gentypes.py Mon Jul 18 09:59:34 2011 +0100
@@ -79,12 +79,13 @@ def libxl_C_type_destroy(ty, v, indent =
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)
@@ -114,12 +115,13 @@ def libxl_C_type_gen_json(ty, v, indent
elif 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_gen_json(f.type, fexpr, indent + " ", nparent)
- s += "}\n"
+ s += " break;\n"
+ s += "}\n"
elif isinstance(ty, libxltypes.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"
diff -r 6bd6decb4f87 -r cf2f4b79c21f tools/libxl/idl.txt
--- a/tools/libxl/idl.txt Mon Jul 18 09:59:33 2011 +0100
+++ b/tools/libxl/idl.txt Mon Jul 18 09:59:34 2011 +0100
@@ -136,13 +136,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 -r 6bd6decb4f87 -r cf2f4b79c21f tools/libxl/libxl.idl
--- a/tools/libxl/libxl.idl Mon Jul 18 09:59:33 2011 +0100
+++ b/tools/libxl/libxl.idl Mon Jul 18 09:59:34 2011 +0100
@@ -160,30 +160,28 @@ libxl_domain_build_info = Struct("domain
("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 6bd6decb4f87 -r cf2f4b79c21f tools/libxl/libxltypes.py
--- a/tools/libxl/libxltypes.py Mon Jul 18 09:59:33 2011 +0100
+++ b/tools/libxl/libxltypes.py Mon Jul 18 09:59:34 2011 +0100
@@ -125,6 +125,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"""
@@ -133,7 +138,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"""
@@ -192,18 +197,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
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|