[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH v8 2/8] libxl/gentypes.py: don't generate default values



If a field:
    0. is not of aggregate type
and
    1. is of array type and the array is not empty
or  2. is of a type which has init_val and has been set to init_val,
or  3. is of builtin type and has been set to internal default value,
or  4. is of a type which has no init_val and has been set to 0

then there's no need to generate output for that field in JSON
output.

Note that 0 can result in output like
  {
    ...
    FOO : { }
    ...
  }
where FOO is aggregate type but all its fields are set to default, hence
no JSON output in {} at all. This is not pretty, but it's still valid
JSON. And the parser should be able to skip touching those fields in the
resulting C structures. When the parser consumes that generated JSON
object, all default values should be automatically filled in.

Also change some non-zero init_vals to LIBXL_* for better readability in
generated C code.

Signed-off-by: Wei Liu <wei.liu2@xxxxxxxxxx>
Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
---
 tools/libxl/gentypes.py     |   33 +++++++++++++++++++++++++++++++--
 tools/libxl/idl.py          |    2 ++
 tools/libxl/idl.txt         |    9 +++++++++
 tools/libxl/libxl_types.idl |   29 +++++++++++++++++------------
 4 files changed, 59 insertions(+), 14 deletions(-)

diff --git a/tools/libxl/gentypes.py b/tools/libxl/gentypes.py
index 01416e7..f06afd9 100644
--- a/tools/libxl/gentypes.py
+++ b/tools/libxl/gentypes.py
@@ -206,6 +206,29 @@ def libxl_C_type_gen_map_key(f, parent, indent = ""):
         s = indent + s
     return s.replace("\n", "\n%s" % indent).rstrip(indent)
 
+def get_init_val(f):
+    if f.init_val is not None:
+        return f.init_val
+    elif f.type.init_val is not None:
+        return f.type.init_val
+    return None
+
+def get_default_expr(f, nparent, fexpr):
+    if isinstance(f.type, idl.Aggregate):
+        return "1 /* always generate JSON output for aggregate type */"
+
+    if isinstance(f.type, idl.Array):
+        return "%s && %s" % (fexpr, nparent + f.type.lenvar.name)
+
+    init_val = get_init_val(f)
+    if init_val is not None:
+        return "%s != %s" % (fexpr, init_val)
+
+    if f.type.check_default_fn:
+        return "!%s(&%s)" % (f.type.check_default_fn, fexpr)
+
+    return "%s" % fexpr
+
 def libxl_C_type_gen_json(ty, v, indent = "    ", parent = None):
     s = ""
     if parent is None:
@@ -255,8 +278,14 @@ def libxl_C_type_gen_json(ty, v, indent = "    ", parent = 
None):
         s += "    goto out;\n"
         for f in [f for f in ty.fields if not f.const and not f.type.private]:
             (nparent,fexpr) = ty.member(v, f, parent is None)
-            s += libxl_C_type_gen_map_key(f, nparent)
-            s += libxl_C_type_gen_json(f.type, fexpr, "", nparent)
+            default_expr = get_default_expr(f, nparent, fexpr)
+            s += "if (%s) {\n" % default_expr
+
+            s += libxl_C_type_gen_map_key(f, nparent, "    ")
+            s += libxl_C_type_gen_json(f.type, fexpr, "    ", nparent)
+
+            s += "}\n"
+
         s += "s = yajl_gen_map_close(hand);\n"
         s += "if (s != yajl_gen_status_ok)\n"
         s += "    goto out;\n"
diff --git a/tools/libxl/idl.py b/tools/libxl/idl.py
index 8b118dd..ada801a 100644
--- a/tools/libxl/idl.py
+++ b/tools/libxl/idl.py
@@ -64,6 +64,8 @@ class Type(object):
         self.init_val = kwargs.setdefault('init_val', None)
         self.autogenerate_init_fn = kwargs.setdefault('autogenerate_init_fn', 
False)
 
+        self.check_default_fn = kwargs.setdefault('check_default_fn', None)
+
         if self.typename is not None and not self.private:
             self.json_gen_fn = kwargs.setdefault('json_gen_fn', self.typename 
+ "_gen_json")
         else:
diff --git a/tools/libxl/idl.txt b/tools/libxl/idl.txt
index 6a53dd8..d47eba8 100644
--- a/tools/libxl/idl.txt
+++ b/tools/libxl/idl.txt
@@ -69,6 +69,15 @@ Type.autogenerate_json: (default: True)
 
  Indicates if the above named Type.json_gen_fn should be autogenerated.
 
+Type.check_default_fn:
+
+ If it's set then calling this function shall return true if this type
+ has been set to default value (internal libxl implementation).
+
+ If this is not set, that means we can check the type against init_val
+ (if it has one) or zero to determine whether the value is default
+ value.
+
 Other simple type-Classes
 -------------------------
 
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index 1018142..7234519 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -5,18 +5,23 @@
 
 namespace("libxl_")
 
-libxl_defbool = Builtin("defbool", passby=PASS_BY_REFERENCE)
+libxl_defbool = Builtin("defbool", passby=PASS_BY_REFERENCE, 
check_default_fn="libxl__defbool_is_default")
 
 libxl_domid = Builtin("domid", json_gen_fn = "yajl_gen_integer", 
autogenerate_json = False)
 libxl_devid = Builtin("devid", json_gen_fn = "yajl_gen_integer", 
autogenerate_json = False, signed = True, init_val="-1")
-libxl_uuid = Builtin("uuid", passby=PASS_BY_REFERENCE)
-libxl_mac = Builtin("mac", passby=PASS_BY_REFERENCE)
-libxl_bitmap = Builtin("bitmap", dispose_fn="libxl_bitmap_dispose", 
passby=PASS_BY_REFERENCE)
-libxl_cpuid_policy_list = Builtin("cpuid_policy_list", 
dispose_fn="libxl_cpuid_dispose", passby=PASS_BY_REFERENCE)
-
-libxl_string_list = Builtin("string_list", 
dispose_fn="libxl_string_list_dispose", passby=PASS_BY_REFERENCE)
-libxl_key_value_list = Builtin("key_value_list", 
dispose_fn="libxl_key_value_list_dispose", passby=PASS_BY_REFERENCE)
-libxl_hwcap = Builtin("hwcap", passby=PASS_BY_REFERENCE)
+libxl_uuid = Builtin("uuid", passby=PASS_BY_REFERENCE, 
check_default_fn="libxl_uuid_is_nil")
+libxl_mac = Builtin("mac", passby=PASS_BY_REFERENCE, 
check_default_fn="libxl__mac_is_default")
+libxl_bitmap = Builtin("bitmap", dispose_fn="libxl_bitmap_dispose", 
passby=PASS_BY_REFERENCE,
+                       check_default_fn="libxl_bitmap_is_empty")
+libxl_cpuid_policy_list = Builtin("cpuid_policy_list", 
dispose_fn="libxl_cpuid_dispose", passby=PASS_BY_REFERENCE,
+                                  
check_default_fn="libxl__cpuid_policy_is_empty")
+
+libxl_string_list = Builtin("string_list", 
dispose_fn="libxl_string_list_dispose", passby=PASS_BY_REFERENCE,
+                            check_default_fn="libxl__string_list_is_empty")
+libxl_key_value_list = Builtin("key_value_list", 
dispose_fn="libxl_key_value_list_dispose", passby=PASS_BY_REFERENCE,
+                               
check_default_fn="libxl__key_value_list_is_empty")
+libxl_hwcap = Builtin("hwcap", passby=PASS_BY_REFERENCE,
+                      check_default_fn="libxl__hwcap_is_default")
 
 #
 # Specific integer types
@@ -49,7 +54,7 @@ libxl_domain_type = Enumeration("domain_type", [
     (-1, "INVALID"),
     (1, "HVM"),
     (2, "PV"),
-    ], init_val = -1)
+    ], init_val = "LIBXL_DOMAIN_TYPE_INVALID")
 
 libxl_device_model_version = Enumeration("device_model_version", [
     (0, "UNKNOWN"),
@@ -95,7 +100,7 @@ libxl_action_on_shutdown = Enumeration("action_on_shutdown", 
[
 
     (5, "COREDUMP_DESTROY"),
     (6, "COREDUMP_RESTART"),
-    ], init_val = 1)
+    ], init_val = "LIBXL_ACTION_ON_SHUTDOWN_DESTROY")
 
 libxl_trigger = Enumeration("trigger", [
     (0, "UNKNOWN"),
@@ -154,7 +159,7 @@ libxl_vga_interface_type = 
Enumeration("vga_interface_type", [
     (1, "CIRRUS"),
     (2, "STD"),
     (3, "NONE"),
-    ], init_val = 1)
+    ], init_val = "LIBXL_VGA_INTERFACE_TYPE_CIRRUS")
 
 libxl_vendor_device = Enumeration("vendor_device", [
     (0, "NONE"),
-- 
1.7.10.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.