* [PATCH v8 0/8] libxl: JSON infrastructure
@ 2014-06-19 17:44 Wei Liu
2014-06-19 17:44 ` [PATCH v8 1/8] libxl_internal: functions to check default values for builtin types Wei Liu
` (7 more replies)
0 siblings, 8 replies; 14+ messages in thread
From: Wei Liu @ 2014-06-19 17:44 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
V8 of the series. This series only contains JSON infrastructure patches.
The JSON infrastructure was tested with running testidl over and over again. A
new testidl executable was generated every run.
Rebased on top of staging.
Legend:
A - acked
D - previous acked, but new change introduced so acked-by dropped
S - the same version as last round
No marker - new patch
Wei.
Wei Liu (8):
S libxl_internal: functions to check default values for builtin types
A libxl/gentypes.py: don't generate default values
libxl: clean up namespace violation
D libxl IDL: generate code to parse libxl__json_object to libxl_FOO
struct
A libxl/gentest.py: test JSON parser
A libxl: copy function for builtin types
A libxl IDL: generate deep copy functions
A libxl/gentest.py: test deep copy functions
tools/libxl/Makefile | 4 +-
tools/libxl/gentest.py | 60 +++++++-
tools/libxl/gentypes.py | 260 +++++++++++++++++++++++++++++++++-
tools/libxl/idl.py | 35 ++++-
tools/libxl/idl.txt | 28 +++-
tools/libxl/libxl.c | 70 ++++++++-
tools/libxl/libxl.h | 26 ++++
tools/libxl/libxl_cpuid.c | 39 ++++-
tools/libxl/libxl_internal.c | 6 +
tools/libxl/libxl_internal.h | 66 ++++++---
tools/libxl/libxl_json.c | 26 ++--
tools/libxl/libxl_nocpuid.c | 12 +-
tools/libxl/libxl_types.idl | 45 +++---
tools/libxl/libxl_types_internal.idl | 4 +-
tools/libxl/libxl_utils.c | 25 ++++
tools/libxl/libxl_utils.h | 4 +
16 files changed, 643 insertions(+), 67 deletions(-)
--
1.7.10.4
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v8 1/8] libxl_internal: functions to check default values for builtin types
2014-06-19 17:44 [PATCH v8 0/8] libxl: JSON infrastructure Wei Liu
@ 2014-06-19 17:44 ` Wei Liu
2014-06-27 11:36 ` Ian Campbell
2014-06-19 17:44 ` [PATCH v8 2/8] libxl/gentypes.py: don't generate default values Wei Liu
` (6 subsequent siblings)
7 siblings, 1 reply; 14+ messages in thread
From: Wei Liu @ 2014-06-19 17:44 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
They will be used in later patch to determine whether we should generate
JSON output for a type. If that type has default value we just skip
generating JSON output.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
tools/libxl/libxl.c | 3 +--
tools/libxl/libxl_internal.c | 6 ++++++
tools/libxl/libxl_internal.h | 27 +++++++++++++++++++++++++++
3 files changed, 34 insertions(+), 2 deletions(-)
diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index 62e251a..1d8e046 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -2860,8 +2860,7 @@ int libxl__device_nic_setdefault(libxl__gc *gc, libxl_device_nic *nic,
nic->model = strdup("rtl8139");
if (!nic->model) return ERROR_NOMEM;
}
- if (!nic->mac[0] && !nic->mac[1] && !nic->mac[2] &&
- !nic->mac[3] && !nic->mac[4] && !nic->mac[5]) {
+ if (libxl__mac_is_default(&nic->mac)) {
const uint8_t *r;
libxl_uuid uuid;
diff --git a/tools/libxl/libxl_internal.c b/tools/libxl/libxl_internal.c
index 6c94d3e..81f8985 100644
--- a/tools/libxl/libxl_internal.c
+++ b/tools/libxl/libxl_internal.c
@@ -307,6 +307,12 @@ _hidden int libxl__compare_macs(libxl_mac *a, libxl_mac *b)
return 0;
}
+_hidden int libxl__mac_is_default(libxl_mac *mac)
+{
+ return (!(*mac)[0] && !(*mac)[1] && !(*mac)[2] &&
+ !(*mac)[3] && !(*mac)[4] && !(*mac)[5]);
+}
+
_hidden int libxl__init_recursive_mutex(libxl_ctx *ctx, pthread_mutex_t *lock)
{
pthread_mutexattr_t attr;
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index a0d4f24..2a8f552 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1551,6 +1551,8 @@ struct libxl__xen_console_reader {
_hidden int libxl__parse_mac(const char *s, libxl_mac mac);
/* compare mac address @a and @b. 0 if the same, -ve if a<b and +ve if a>b */
_hidden int libxl__compare_macs(libxl_mac *a, libxl_mac *b);
+/* return true if mac address is all zero (the default value) */
+_hidden int libxl__mac_is_default(libxl_mac *mac);
/* init a recursive mutex */
_hidden int libxl__init_recursive_mutex(libxl_ctx *ctx, pthread_mutex_t *lock);
@@ -3097,6 +3099,10 @@ void libxl__numa_candidate_put_nodemap(libxl__gc *gc,
#define LIBXL__DEFBOOL_STR_DEFAULT "<default>"
#define LIBXL__DEFBOOL_STR_FALSE "False"
#define LIBXL__DEFBOOL_STR_TRUE "True"
+static inline int libxl__defbool_is_default(libxl_defbool *db)
+{
+ return !db->val;
+}
/*
* Inserts "elm_new" into the sorted list "head".
@@ -3180,6 +3186,27 @@ int libxl__uint64_parse_json(libxl__gc *gc, const libxl__json_object *o,
int libxl__string_parse_json(libxl__gc *gc, const libxl__json_object *o,
char **p);
+/* This always return false, there's no "default value" for hw cap */
+static inline int libxl__hwcap_is_default(libxl_hwcap *hwcap)
+{
+ return 0;
+}
+
+static inline int libxl__string_list_is_empty(libxl_string_list *psl)
+{
+ return !libxl_string_list_length(psl);
+}
+
+static inline int libxl__key_value_list_is_empty(libxl_key_value_list *pkvl)
+{
+ return !libxl_key_value_list_length(pkvl);
+}
+
+static inline int libxl__cpuid_policy_is_empty(libxl_cpuid_policy_list *pl)
+{
+ return !libxl_cpuid_policy_list_length(pl);
+}
+
#endif
/*
--
1.7.10.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v8 2/8] libxl/gentypes.py: don't generate default values
2014-06-19 17:44 [PATCH v8 0/8] libxl: JSON infrastructure Wei Liu
2014-06-19 17:44 ` [PATCH v8 1/8] libxl_internal: functions to check default values for builtin types Wei Liu
@ 2014-06-19 17:44 ` Wei Liu
2014-06-27 11:37 ` Ian Campbell
2014-06-19 17:44 ` [PATCH v8 3/8] libxl: clean up namespace violation Wei Liu
` (5 subsequent siblings)
7 siblings, 1 reply; 14+ messages in thread
From: Wei Liu @ 2014-06-19 17:44 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
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@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
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
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v8 3/8] libxl: clean up namespace violation
2014-06-19 17:44 [PATCH v8 0/8] libxl: JSON infrastructure Wei Liu
2014-06-19 17:44 ` [PATCH v8 1/8] libxl_internal: functions to check default values for builtin types Wei Liu
2014-06-19 17:44 ` [PATCH v8 2/8] libxl/gentypes.py: don't generate default values Wei Liu
@ 2014-06-19 17:44 ` Wei Liu
2014-06-27 11:37 ` Ian Campbell
2014-06-19 17:44 ` [PATCH v8 4/8] libxl IDL: generate code to parse libxl__json_object to libxl_FOO struct Wei Liu
` (4 subsequent siblings)
7 siblings, 1 reply; 14+ messages in thread
From: Wei Liu @ 2014-06-19 17:44 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
In 752f181f ("libxl_json: introduce parser functions for builtin types")
a bunch of parser functions were introduced. Unfortunately they
polluted the public namespace with a prefix "libxl_", while they should
be internal functions.
This patch changes the prefix to "libxl__". No functional change
introduced.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
tools/libxl/libxl_cpuid.c | 6 +++---
tools/libxl/libxl_internal.h | 36 ++++++++++++++++++------------------
tools/libxl/libxl_json.c | 26 +++++++++++++-------------
tools/libxl/libxl_nocpuid.c | 6 +++---
4 files changed, 37 insertions(+), 37 deletions(-)
diff --git a/tools/libxl/libxl_cpuid.c b/tools/libxl/libxl_cpuid.c
index 1f2bcd5..30c9ec3 100644
--- a/tools/libxl/libxl_cpuid.c
+++ b/tools/libxl/libxl_cpuid.c
@@ -398,9 +398,9 @@ out:
return s;
}
-int libxl_cpuid_policy_list_parse_json(libxl__gc *gc,
- const libxl__json_object *o,
- libxl_cpuid_policy_list *p)
+int libxl__cpuid_policy_list_parse_json(libxl__gc *gc,
+ const libxl__json_object *o,
+ libxl_cpuid_policy_list *p)
{
int i, size;
libxl_cpuid_policy_list l;
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 2a8f552..9e8bc4c 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -3153,26 +3153,26 @@ static inline int libxl__defbool_is_default(libxl_defbool *db)
*/
#define CTYPE(isfoo,c) (isfoo((unsigned char)(c)))
-int libxl_defbool_parse_json(libxl__gc *gc, const libxl__json_object *o,
- libxl_defbool *p);
+int libxl__defbool_parse_json(libxl__gc *gc, const libxl__json_object *o,
+ libxl_defbool *p);
int libxl__bool_parse_json(libxl__gc *gc, const libxl__json_object *o,
bool *p);
-int libxl_mac_parse_json(libxl__gc *gc, const libxl__json_object *o,
- libxl_mac *p);
-int libxl_bitmap_parse_json(libxl__gc *gc, const libxl__json_object *o,
- libxl_bitmap *p);
-int libxl_uuid_parse_json(libxl__gc *gc, const libxl__json_object *o,
- libxl_uuid *p);
-int libxl_cpuid_policy_list_parse_json(libxl__gc *gc,
- const libxl__json_object *o,
- libxl_cpuid_policy_list *p);
-int libxl_string_list_parse_json(libxl__gc *gc, const libxl__json_object *o,
- libxl_string_list *p);
-int libxl_key_value_list_parse_json(libxl__gc *gc,
- const libxl__json_object *o,
- libxl_key_value_list *p);
-int libxl_hwcap_parse_json(libxl__gc *gc, const libxl__json_object *o,
- libxl_hwcap *p);
+int libxl__mac_parse_json(libxl__gc *gc, const libxl__json_object *o,
+ libxl_mac *p);
+int libxl__bitmap_parse_json(libxl__gc *gc, const libxl__json_object *o,
+ libxl_bitmap *p);
+int libxl__uuid_parse_json(libxl__gc *gc, const libxl__json_object *o,
+ libxl_uuid *p);
+int libxl__cpuid_policy_list_parse_json(libxl__gc *gc,
+ const libxl__json_object *o,
+ libxl_cpuid_policy_list *p);
+int libxl__string_list_parse_json(libxl__gc *gc, const libxl__json_object *o,
+ libxl_string_list *p);
+int libxl__key_value_list_parse_json(libxl__gc *gc,
+ const libxl__json_object *o,
+ libxl_key_value_list *p);
+int libxl__hwcap_parse_json(libxl__gc *gc, const libxl__json_object *o,
+ libxl_hwcap *p);
int libxl__int_parse_json(libxl__gc *gc, const libxl__json_object *o,
void *p);
int libxl__uint8_parse_json(libxl__gc *gc, const libxl__json_object *o,
diff --git a/tools/libxl/libxl_json.c b/tools/libxl/libxl_json.c
index fb9baf8..dd0d73e 100644
--- a/tools/libxl/libxl_json.c
+++ b/tools/libxl/libxl_json.c
@@ -100,8 +100,8 @@ yajl_gen_status libxl_defbool_gen_json(yajl_gen hand,
return libxl__yajl_gen_asciiz(hand, libxl_defbool_to_string(*db));
}
-int libxl_defbool_parse_json(libxl__gc *gc, const libxl__json_object *o,
- libxl_defbool *p)
+int libxl__defbool_parse_json(libxl__gc *gc, const libxl__json_object *o,
+ libxl_defbool *p)
{
const char *s;
@@ -144,8 +144,8 @@ yajl_gen_status libxl_uuid_gen_json(yajl_gen hand,
return yajl_gen_string(hand, (const unsigned char *)buf, LIBXL_UUID_FMTLEN);
}
-int libxl_uuid_parse_json(libxl__gc *gc, const libxl__json_object *o,
- libxl_uuid *p)
+int libxl__uuid_parse_json(libxl__gc *gc, const libxl__json_object *o,
+ libxl_uuid *p)
{
if (!libxl__json_object_is_string(o))
return ERROR_FAIL;
@@ -173,7 +173,7 @@ out:
return s;
}
-int libxl_bitmap_parse_json(libxl__gc *gc, const libxl__json_object *o,
+int libxl__bitmap_parse_json(libxl__gc *gc, const libxl__json_object *o,
libxl_bitmap *p)
{
int i;
@@ -234,8 +234,8 @@ out:
return s;
}
-int libxl_key_value_list_parse_json(libxl__gc *gc, const libxl__json_object *o,
- libxl_key_value_list *p)
+int libxl__key_value_list_parse_json(libxl__gc *gc, const libxl__json_object *o,
+ libxl_key_value_list *p)
{
libxl__json_map_node *node = NULL;
flexarray_t *maps = NULL;
@@ -290,8 +290,8 @@ out:
return s;
}
-int libxl_string_list_parse_json(libxl__gc *gc, const libxl__json_object *o,
- libxl_string_list *p)
+int libxl__string_list_parse_json(libxl__gc *gc, const libxl__json_object *o,
+ libxl_string_list *p)
{
const libxl__json_object *t;
libxl_string_list l;
@@ -329,8 +329,8 @@ yajl_gen_status libxl_mac_gen_json(yajl_gen hand, libxl_mac *mac)
return yajl_gen_string(hand, (const unsigned char *)buf, LIBXL_MAC_FMTLEN);
}
-int libxl_mac_parse_json(libxl__gc *gc, const libxl__json_object *o,
- libxl_mac *p)
+int libxl__mac_parse_json(libxl__gc *gc, const libxl__json_object *o,
+ libxl_mac *p)
{
if (!libxl__json_object_is_string(o))
return ERROR_FAIL;
@@ -356,8 +356,8 @@ out:
return s;
}
-int libxl_hwcap_parse_json(libxl__gc *gc, const libxl__json_object *o,
- libxl_hwcap *p)
+int libxl__hwcap_parse_json(libxl__gc *gc, const libxl__json_object *o,
+ libxl_hwcap *p)
{
int i;
diff --git a/tools/libxl/libxl_nocpuid.c b/tools/libxl/libxl_nocpuid.c
index eb525fc..e98906a 100644
--- a/tools/libxl/libxl_nocpuid.c
+++ b/tools/libxl/libxl_nocpuid.c
@@ -44,9 +44,9 @@ yajl_gen_status libxl_cpuid_policy_list_gen_json(yajl_gen hand,
return 0;
}
-int libxl_cpuid_policy_list_parse_json(libxl__gc *gc,
- const libxl__json_object *o,
- libxl_cpuid_policy_list *p)
+int libxl__cpuid_policy_list_parse_json(libxl__gc *gc,
+ const libxl__json_object *o,
+ libxl_cpuid_policy_list *p)
{
return 0;
}
--
1.7.10.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v8 4/8] libxl IDL: generate code to parse libxl__json_object to libxl_FOO struct
2014-06-19 17:44 [PATCH v8 0/8] libxl: JSON infrastructure Wei Liu
` (2 preceding siblings ...)
2014-06-19 17:44 ` [PATCH v8 3/8] libxl: clean up namespace violation Wei Liu
@ 2014-06-19 17:44 ` Wei Liu
2014-06-27 11:40 ` Ian Campbell
2014-06-19 17:44 ` [PATCH v8 5/8] libxl/gentest.py: test JSON parser Wei Liu
` (3 subsequent siblings)
7 siblings, 1 reply; 14+ messages in thread
From: Wei Liu @ 2014-06-19 17:44 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
libxl_FOO_parse_json functions are generated.
Note that these functions are used to parse libxl__json_object to
libxl__FOO struct. They don't consume JSON string.
The new function definitions are generated to new header files called
__libxl_types_*_private.h so that they don't contaminate public header.
The suffix "private is chosen so we can avoid clashing with
libxl_types_internal.idl stuffs.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
Changes since last version:
1. use _private suffix for new header file name
2. use libxl__ namespace
3. generate function prototypes to proper header files
Change since last version: output parser function definitions to
dedicated header file.
---
tools/libxl/Makefile | 4 +-
tools/libxl/gentypes.py | 160 +++++++++++++++++++++++++++++++++-
tools/libxl/idl.py | 20 +++++
tools/libxl/idl.txt | 7 +-
tools/libxl/libxl.h | 14 +++
tools/libxl/libxl_internal.h | 3 +
tools/libxl/libxl_types.idl | 27 +++---
tools/libxl/libxl_types_internal.idl | 4 +-
8 files changed, 221 insertions(+), 18 deletions(-)
diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile
index 7fc42c8..b1ad8d4 100644
--- a/tools/libxl/Makefile
+++ b/tools/libxl/Makefile
@@ -184,8 +184,10 @@ $(LIBXL_OBJS) $(LIBXL_TEST_OBJS) $(LIBXLU_OBJS) \
$(LIBXL_OBJS) $(LIBXL_TEST_OBJS): libxl_internal.h
_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
+ $(PYTHON) gentypes.py libxl_type$*.idl __libxl_type$*.h __libxl_type$*_private.h \
+ __libxl_type$*_json.h __libxl_type$*.c
$(call move-if-changed,__libxl_type$*.h,_libxl_type$*.h)
+ $(call move-if-changed,__libxl_type$*_private.h,_libxl_type$*_private.h)
$(call move-if-changed,__libxl_type$*_json.h,_libxl_type$*_json.h)
$(call move-if-changed,__libxl_type$*.c,_libxl_type$*.c)
diff --git a/tools/libxl/gentypes.py b/tools/libxl/gentypes.py
index f06afd9..6cdeaa8 100644
--- a/tools/libxl/gentypes.py
+++ b/tools/libxl/gentypes.py
@@ -312,6 +312,116 @@ def libxl_C_type_to_json(ty, v, indent = " "):
s = indent + s
return s.replace("\n", "\n%s" % indent).rstrip(indent)
+def libxl_C_type_parse_json(ty, w, v, indent = " ", parent = None, discriminator = None):
+ s = ""
+ if parent is None:
+ s += "int rc = 0;\n"
+ s += "const libxl__json_object *x = o;\n"
+
+ if isinstance(ty, idl.Array):
+ if parent is None:
+ raise Exception("Array type must have a parent")
+ if discriminator is not None:
+ raise Exception("Only KeyedUnion can have discriminator")
+ lenvar = parent + ty.lenvar.name
+ s += "{\n"
+ s += " libxl__json_object *t;\n"
+ s += " int i;\n"
+ s += " if (!libxl__json_object_is_array(x)) {\n"
+ s += " rc = -1;\n"
+ s += " goto out;\n"
+ s += " }\n"
+ s += " %s = x->u.array->count;\n" % lenvar
+ s += " %s = libxl__calloc(NOGC, %s, sizeof(*%s));\n" % (v, lenvar, v)
+ s += " if (!%s && %s != 0) {\n" % (v, lenvar)
+ s += " rc = -1;\n"
+ s += " goto out;\n"
+ s += " }\n"
+ s += " for (i=0; (t=libxl__json_array_get(x,i)); i++) {\n"
+ s += libxl_C_type_parse_json(ty.elem_type, "t", v+"[i]",
+ indent + " ", parent)
+ s += " }\n"
+ s += " if (i != %s) {\n" % lenvar
+ s += " rc = -1;\n"
+ s += " goto out;\n"
+ s += " }\n"
+ s += "}\n"
+ elif isinstance(ty, idl.Enumeration):
+ if discriminator is not None:
+ raise Exception("Only KeyedUnion can have discriminator")
+ s += "{\n"
+ s += " const char *enum_str;\n"
+ s += " if (!libxl__json_object_is_string(x)) {\n"
+ s += " rc = -1;\n"
+ s += " goto out;\n"
+ s += " }\n"
+ s += " enum_str = libxl__json_object_get_string(x);\n"
+ s += " rc = %s_from_string(enum_str, %s);\n" % (ty.typename, ty.pass_arg(v, parent is None, idl.PASS_BY_REFERENCE))
+ s += " if (rc)\n"
+ s += " goto out;\n"
+ s += "}\n"
+ elif isinstance(ty, idl.KeyedUnion):
+ if parent is None:
+ raise Exception("KeyedUnion type must have a parent")
+ if discriminator is None:
+ raise Excpetion("KeyedUnion type must have a discriminator")
+ for f in ty.fields:
+ if f.enumname != discriminator:
+ continue
+ (nparent,fexpr) = ty.member(v, f, parent is None)
+ if f.type is not None:
+ s += libxl_C_type_parse_json(f.type, w, fexpr, indent + " ", nparent)
+ elif isinstance(ty, idl.Struct) and (parent is None or ty.json_parse_fn is None):
+ if discriminator is not None:
+ raise Exception("Only KeyedUnion can have discriminator")
+ for f in [f for f in ty.fields if not f.const and not f.type.private]:
+ saved_var_name = "saved_%s" % f.name
+ s += "{\n"
+ s += " const libxl__json_object *%s = NULL;\n" % saved_var_name
+ s += " %s = x;\n" % saved_var_name
+ if isinstance(f.type, idl.KeyedUnion):
+ for x in f.type.fields:
+ s += " x = libxl__json_map_get(\"%s\", %s, JSON_MAP);\n" % \
+ (f.type.keyvar.name + "." + x.name, w)
+ s += " if (x) {\n"
+ (nparent, fexpr) = ty.member(v, f.type.keyvar, parent is None)
+ s += " %s_init_type(%s, %s);\n" % (ty.typename, v, x.enumname)
+ (nparent,fexpr) = ty.member(v, f, parent is None)
+ s += libxl_C_type_parse_json(f.type, "x", fexpr, " ", nparent, x.enumname)
+ s += " }\n"
+ else:
+ s += " x = libxl__json_map_get(\"%s\", %s, %s);\n" % (f.name, w, f.type.json_parse_type)
+ s += " if (x) {\n"
+ (nparent,fexpr) = ty.member(v, f, parent is None)
+ s += libxl_C_type_parse_json(f.type, "x", fexpr, " ", nparent)
+ s += " }\n"
+ s += " x = %s;\n" % saved_var_name
+ s += "}\n"
+ else:
+ if discriminator is not None:
+ raise Exception("Only KeyedUnion can have discriminator")
+ if ty.json_parse_fn is not None:
+ s += "rc = %s(gc, %s, &%s);\n" % (ty.json_parse_fn, w, v)
+ s += "if (rc)\n"
+ s += " goto out;\n"
+
+ if parent is None:
+ s += "out:\n"
+ s += "return rc;\n"
+
+ if s != "":
+ s = indent +s
+ return s.replace("\n", "\n%s" % indent).rstrip(indent)
+
+def libxl_C_type_from_json(ty, v, w, indent = " "):
+ s = ""
+ parse = "(libxl__json_parse_callback)&%s_parse_json" % (ty.namespace + "_" + ty.rawname)
+ s += "return libxl__object_from_json(ctx, \"%s\", %s, %s, %s);\n" % (ty.typename, parse, v, w)
+
+ if s != "":
+ s = indent + s
+ return s.replace("\n", "\n%s" % indent).rstrip(indent)
+
def libxl_C_enum_to_string(ty, e, indent = " "):
s = ""
s += "switch(%s) {\n" % e
@@ -350,11 +460,11 @@ def libxl_C_enum_from_string(ty, str, e, indent = " "):
if __name__ == '__main__':
- if len(sys.argv) != 5:
- print >>sys.stderr, "Usage: gentypes.py <idl> <header> <header-json> <implementation>"
+ if len(sys.argv) != 6:
+ print >>sys.stderr, "Usage: gentypes.py <idl> <header> <header-private> <header-json> <implementation>"
sys.exit(1)
- (_, idlname, header, header_json, impl) = sys.argv
+ (_, idlname, header, header_private, header_json, impl) = sys.argv
(builtins,types) = idl.parse(idlname)
@@ -390,6 +500,8 @@ if __name__ == '__main__':
ku.keyvar.type.make_arg(ku.keyvar.name)))
if ty.json_gen_fn is not None:
f.write("%schar *%s_to_json(libxl_ctx *ctx, %s);\n" % (ty.hidden(), ty.typename, ty.make_arg("p")))
+ if ty.json_parse_fn is not None:
+ f.write("%sint %s_from_json(libxl_ctx *ctx, %s, const char *s);\n" % (ty.hidden(), ty.typename, ty.make_arg("p", passby=idl.PASS_BY_REFERENCE)))
if isinstance(ty, idl.Enumeration):
f.write("%sconst char *%s_to_string(%s);\n" % (ty.hidden(), ty.typename, ty.make_arg("p")))
f.write("%sint %s_from_string(const char *s, %s);\n" % (ty.hidden(), ty.typename, ty.make_arg("e", passby=idl.PASS_BY_REFERENCE)))
@@ -423,6 +535,32 @@ if __name__ == '__main__':
f.write("""#endif /* %s */\n""" % header_json_define)
f.close()
+ print "outputting libxl type internal definitions to %s" % header_private
+
+ f = open(header_private, "w")
+
+ header_private_define = header_private.upper().replace('.','_')
+ f.write("""#ifndef %s
+#define %s
+
+/*
+ * DO NOT EDIT.
+ *
+ * This file is autogenerated by
+ * "%s"
+ */
+
+""" % (header_private_define, header_private_define, " ".join(sys.argv)))
+
+ for ty in [ty for ty in types if ty.json_parse_fn is not None]:
+ f.write("%sint %s_parse_json(libxl__gc *gc, const libxl__json_object *o, %s);\n" % \
+ (ty.hidden(), ty.namespace + "_" + ty.rawname,
+ ty.make_arg("p", passby=idl.PASS_BY_REFERENCE)))
+
+ f.write("\n")
+ f.write("""#endif /* %s */\n""" % header_json_define)
+ f.close()
+
print "outputting libxl type implementations to %s" % impl
f = open(impl, "w")
@@ -486,4 +624,20 @@ if __name__ == '__main__':
f.write("}\n")
f.write("\n")
+ for ty in [t for t in types if t.json_parse_fn is not None]:
+ f.write("int %s_parse_json(libxl__gc *gc, const libxl__json_object *%s, %s)\n" % \
+ (ty.namespace + "_" + ty.rawname,"o",ty.make_arg("p", passby=idl.PASS_BY_REFERENCE)))
+ f.write("{\n")
+ f.write(libxl_C_type_parse_json(ty, "o", "p"))
+ f.write("}\n")
+ f.write("\n")
+
+ f.write("int %s_from_json(libxl_ctx *ctx, %s, const char *s)\n" % (ty.typename, ty.make_arg("p", passby=idl.PASS_BY_REFERENCE)))
+ f.write("{\n")
+ if not isinstance(ty, idl.Enumeration):
+ f.write(" %s_init(p);\n" % ty.typename)
+ f.write(libxl_C_type_from_json(ty, "p", "s"))
+ f.write("}\n")
+ f.write("\n")
+
f.close()
diff --git a/tools/libxl/idl.py b/tools/libxl/idl.py
index ada801a..63557db 100644
--- a/tools/libxl/idl.py
+++ b/tools/libxl/idl.py
@@ -68,8 +68,17 @@ class Type(object):
if self.typename is not None and not self.private:
self.json_gen_fn = kwargs.setdefault('json_gen_fn', self.typename + "_gen_json")
+ self.json_parse_type = kwargs.setdefault('json_parse_type', "JSON_ANY")
+ if self.namespace is not None:
+ self.json_parse_fn = kwargs.setdefault('json_parse_fn',
+ self.namespace + "_" + self.rawname + "_parse_json")
+ else:
+ self.json_parse_fn = kwargs.setdefault('json_parse_fn',
+ self.typename + "_parse_json")
else:
self.json_gen_fn = kwargs.setdefault('json_gen_fn', None)
+ self.json_parse_type = kwargs.setdefault('json_parse_type', None)
+ self.json_parse_fn = kwargs.setdefault('json_parse_fn', None)
self.autogenerate_json = kwargs.setdefault('autogenerate_json', True)
@@ -121,6 +130,9 @@ class Number(Builtin):
kwargs.setdefault('dispose_fn', None)
kwargs.setdefault('signed', False)
kwargs.setdefault('json_gen_fn', "yajl_gen_integer")
+ kwargs.setdefault('json_parse_type', "JSON_INTEGER")
+ # json_parse_fn might be overriden on specific type
+ kwargs.setdefault('json_parse_fn', "libxl__int_parse_json")
self.signed = kwargs['signed']
Builtin.__init__(self, ctype, **kwargs)
@@ -128,6 +140,7 @@ class UInt(Number):
def __init__(self, w, **kwargs):
kwargs.setdefault('namespace', None)
kwargs.setdefault('dispose_fn', None)
+ kwargs.setdefault('json_parse_fn', "libxl__uint%d_parse_json" % w)
Number.__init__(self, "uint%d_t" % w, **kwargs)
self.width = w
@@ -144,6 +157,7 @@ class EnumerationValue(object):
class Enumeration(Type):
def __init__(self, typename, values, **kwargs):
kwargs.setdefault('dispose_fn', None)
+ kwargs.setdefault('json_parse_type', "JSON_STRING")
Type.__init__(self, typename, **kwargs)
self.value_namespace = kwargs.setdefault('value_namespace',
@@ -173,6 +187,7 @@ class Field(object):
class Aggregate(Type):
"""A type containing a collection of other types"""
def __init__(self, kind, typename, fields, **kwargs):
+ kwargs.setdefault('json_parse_type', "JSON_MAP")
Type.__init__(self, typename, **kwargs)
if self.typename is not None:
@@ -259,6 +274,8 @@ class KeyedUnion(Aggregate):
void = Builtin("void *", namespace = None)
bool = Builtin("bool", namespace = None,
json_gen_fn = "yajl_gen_bool",
+ json_parse_type = "JSON_BOOL",
+ json_parse_fn = "libxl__bool_parse_json",
autogenerate_json = False)
size_t = Number("size_t", namespace = None)
@@ -272,12 +289,15 @@ uint64 = UInt(64, json_gen_fn = "libxl__uint64_gen_json")
string = Builtin("char *", namespace = None, dispose_fn = "free",
json_gen_fn = "libxl__string_gen_json",
+ json_parse_type = "JSON_STRING | JSON_NULL",
+ json_parse_fn = "libxl__string_parse_json",
autogenerate_json = False)
class Array(Type):
"""An array of the same type"""
def __init__(self, elem_type, lenvar_name, **kwargs):
kwargs.setdefault('dispose_fn', 'free')
+ kwargs.setdefault('json_parse_type', 'JSON_ARRAY')
Type.__init__(self, namespace=elem_type.namespace, typename=elem_type.rawname + " *", **kwargs)
lv_kwargs = dict([(x.lstrip('lenvar_'),y) for (x,y) in kwargs.items() if x.startswith('lenvar_')])
diff --git a/tools/libxl/idl.txt b/tools/libxl/idl.txt
index d47eba8..87c4952 100644
--- a/tools/libxl/idl.txt
+++ b/tools/libxl/idl.txt
@@ -65,9 +65,14 @@ Type.json_gen_fn: (default: typename + "_gen_json" or None if type == None)
The name of the C function which will generate a YAJL data structure
representing this type.
+Type.json_parse_fn: (default: typename + "_parse_json" or None if type == None)
+
+ The name of the C function which will parse a libxl JSON structure
+ representing this type to C type.
+
Type.autogenerate_json: (default: True)
- Indicates if the above named Type.json_gen_fn should be autogenerated.
+ Indicates if the above named Type.json_*_fn should be autogenerated.
Type.check_default_fn:
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 69ceac8..e52a43f 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -305,6 +305,20 @@
*
* Generates a JSON object from "p" in the form of a NULL terminated
* string.
+ *
+ * <type *> libxl_<type>_from_json(const char *json)
+ * int libxl_<type>_from_json(const char *json)
+ *
+ * Parses "json" and returns:
+ *
+ * an int value, if <type> is enumeration type. The value is the enum value
+ * representing the respective string in "json".
+ *
+ * an instance of <type>, if <type> is aggregate type. The returned
+ * instance has its fields filled in by the parser according to "json".
+ *
+ * If the parsing fails, caller cannot rely on the value / instance
+ * returned.
*/
#ifndef LIBXL_H
#define LIBXL_H
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 9e8bc4c..a5803d2 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -3186,6 +3186,9 @@ int libxl__uint64_parse_json(libxl__gc *gc, const libxl__json_object *o,
int libxl__string_parse_json(libxl__gc *gc, const libxl__json_object *o,
char **p);
+#include "_libxl_types_private.h"
+#include "_libxl_types_internal_private.h"
+
/* This always return false, there's no "default value" for hw cap */
static inline int libxl__hwcap_is_default(libxl_hwcap *hwcap)
{
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index 7234519..2cb856c 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -5,22 +5,25 @@
namespace("libxl_")
-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, 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,
+libxl_defbool = Builtin("defbool", json_parse_type="JSON_STRING", passby=PASS_BY_REFERENCE,
+ check_default_fn="libxl__defbool_is_default")
+
+libxl_domid = Builtin("domid", json_gen_fn = "yajl_gen_integer", json_parse_fn = "libxl__uint32_parse_json",
+ json_parse_type = "JSON_INTEGER", autogenerate_json = False)
+libxl_devid = Builtin("devid", json_gen_fn = "yajl_gen_integer", json_parse_fn = "libxl__int_parse_json",
+ json_parse_type = "JSON_INTEGER", autogenerate_json = False, signed = True, init_val="-1")
+libxl_uuid = Builtin("uuid", json_parse_type="JSON_STRING", passby=PASS_BY_REFERENCE, check_default_fn="libxl_uuid_is_nil")
+libxl_mac = Builtin("mac", json_parse_type="JSON_STRING", passby=PASS_BY_REFERENCE, check_default_fn="libxl__mac_is_default")
+libxl_bitmap = Builtin("bitmap", json_parse_type="JSON_ARRAY", 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")
+ json_parse_type="JSON_ARRAY", 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")
+ json_parse_type="JSON_ARRAY", 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,
+ json_parse_type="JSON_MAP", check_default_fn="libxl__key_value_list_is_empty")
+libxl_hwcap = Builtin("hwcap", passby=PASS_BY_REFERENCE, json_parse_type="JSON_ARRAY",
check_default_fn="libxl__hwcap_is_default")
#
@@ -586,7 +589,7 @@ libxl_event_type = Enumeration("event_type", [
libxl_ev_user = UInt(64)
-libxl_ev_link = Builtin("ev_link", passby=PASS_BY_REFERENCE, private=True)
+libxl_ev_link = Builtin("ev_link", json_parse_type="JSON_STRING", passby=PASS_BY_REFERENCE, private=True)
libxl_event = Struct("event",[
("link", libxl_ev_link),
diff --git a/tools/libxl/libxl_types_internal.idl b/tools/libxl/libxl_types_internal.idl
index a964851..17533f1 100644
--- a/tools/libxl/libxl_types_internal.idl
+++ b/tools/libxl/libxl_types_internal.idl
@@ -1,7 +1,9 @@
namespace("libxl__")
hidden(True)
-libxl_domid = Builtin("domid", namespace="libxl_", json_gen_fn = "yajl_gen_integer")
+libxl_domid = Builtin("domid", namespace="libxl_", json_gen_fn = "yajl_gen_integer",
+ json_parse_fn = "libxl__uint32_parse_json", json_parse_type = "JSON_INTEGER",
+ autogenerate_json = False)
libxl__qmp_message_type = Enumeration("qmp_message_type", [
(1, "QMP"),
--
1.7.10.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v8 5/8] libxl/gentest.py: test JSON parser
2014-06-19 17:44 [PATCH v8 0/8] libxl: JSON infrastructure Wei Liu
` (3 preceding siblings ...)
2014-06-19 17:44 ` [PATCH v8 4/8] libxl IDL: generate code to parse libxl__json_object to libxl_FOO struct Wei Liu
@ 2014-06-19 17:44 ` Wei Liu
2014-06-19 17:44 ` [PATCH v8 6/8] libxl: copy function for builtin types Wei Liu
` (2 subsequent siblings)
7 siblings, 0 replies; 14+ messages in thread
From: Wei Liu @ 2014-06-19 17:44 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
The test is done in following steps:
1. initialise libxl_FOO struct
2. generate JSON string A for libxl_FOO struct FOO1
3. convert JSON string A to libxl_FOO struct FOO2
4. generate JSON string B for libxl_FOO struct FOO2
5. compare A and B
If A and B are identical then we are good.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
tools/libxl/gentest.py | 23 ++++++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)
diff --git a/tools/libxl/gentest.py b/tools/libxl/gentest.py
index eb9a21b..b92d092 100644
--- a/tools/libxl/gentest.py
+++ b/tools/libxl/gentest.py
@@ -225,10 +225,11 @@ int main(int argc, char **argv)
""")
for ty in types:
- f.write(" %s %s_val;\n" % (ty.typename, ty.typename))
+ f.write(" %s %s_val, %s_val_new;\n" % \
+ (ty.typename, ty.typename, ty.typename))
f.write("""
int rc;
- char *s;
+ char *s, *new_s;
xentoollog_logger_stdiostream *logger;
libxl_ctx *ctx;
@@ -240,20 +241,36 @@ int main(int argc, char **argv)
exit(1);
}
""")
- f.write(" printf(\"Testing TYPE_to_json()\\n\");\n")
+ f.write(" printf(\"Testing TYPE_to/from_json()\\n\");\n")
f.write(" printf(\"----------------------\\n\");\n")
f.write(" printf(\"\\n\");\n")
for ty in [t for t in types if t.json_gen_fn is not None]:
arg = ty.typename + "_val"
f.write(" %s_rand_init(%s);\n" % (ty.typename, \
ty.pass_arg(arg, isref=False, passby=idl.PASS_BY_REFERENCE)))
+ if not isinstance(ty, idl.Enumeration):
+ f.write(" %s_init(%s_new);\n" % (ty.typename, \
+ 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(" if (s == NULL) abort();\n")
+ f.write(" rc = %s_from_json(ctx, &%s_val_new, s);\n" % \
+ (ty.typename, ty.typename))
+ f.write(" if (rc) abort();\n")
+ f.write(" new_s = %s_to_json(ctx, %s_new);\n" % \
+ (ty.typename, ty.pass_arg(arg, isref=False)))
+ f.write(" if (new_s == NULL) abort();\n")
+ f.write(" if (strcmp(s, new_s)) {\n")
+ f.write(" printf(\"Huh? Regenerated string different from original string.\\n\");\n")
+ f.write(" printf(\"Regenerated string: %s\\n\", new_s);\n")
+ f.write(" abort();\n")
+ f.write(" }\n")
f.write(" free(s);\n")
+ f.write(" free(new_s);\n")
if ty.dispose_fn is not None:
f.write(" %s(&%s_val);\n" % (ty.dispose_fn, ty.typename))
+ f.write(" %s(&%s_val_new);\n" % (ty.dispose_fn, ty.typename))
f.write("\n")
f.write(" printf(\"Testing Enumerations\\n\");\n")
--
1.7.10.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v8 6/8] libxl: copy function for builtin types
2014-06-19 17:44 [PATCH v8 0/8] libxl: JSON infrastructure Wei Liu
` (4 preceding siblings ...)
2014-06-19 17:44 ` [PATCH v8 5/8] libxl/gentest.py: test JSON parser Wei Liu
@ 2014-06-19 17:44 ` Wei Liu
2014-06-19 17:44 ` [PATCH v8 7/8] libxl IDL: generate deep copy functions Wei Liu
2014-06-19 17:44 ` [PATCH v8 8/8] libxl/gentest.py: test " Wei Liu
7 siblings, 0 replies; 14+ messages in thread
From: Wei Liu @ 2014-06-19 17:44 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
These functions will be used in later patch to deep-copy a structure.
Functions introduced:
* libxl_string_list_copy
* libxl_key_value_list_copy
* libxl_hwcap_copy
* libxl_mac_copy
* libxl_cpuid_policy_list_copy
* libxl_string_copy
* libxl_bitmap_copy_alloc
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
tools/libxl/libxl.c | 67 +++++++++++++++++++++++++++++++++++++++++++
tools/libxl/libxl.h | 12 ++++++++
tools/libxl/libxl_cpuid.c | 33 +++++++++++++++++++++
tools/libxl/libxl_nocpuid.c | 6 ++++
tools/libxl/libxl_utils.c | 25 ++++++++++++++++
tools/libxl/libxl_utils.h | 4 +++
6 files changed, 147 insertions(+)
diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index 1d8e046..183a832 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -205,6 +205,29 @@ void libxl_string_list_dispose(libxl_string_list *psl)
free(sl);
}
+void libxl_string_list_copy(libxl_ctx *ctx,
+ libxl_string_list *dst,
+ libxl_string_list *src)
+{
+ GC_INIT(ctx);
+ int i, len;
+
+ if (!*src) {
+ *dst = NULL;
+ goto out;
+ }
+
+ len = libxl_string_list_length(src);
+ /* one extra slot for sentinel */
+ *dst = libxl__calloc(NOGC, len + 1, sizeof(char *));
+
+ for (i = 0; i < len; i++)
+ (*dst)[i] = libxl__strdup(NOGC, (*src)[i]);
+
+out:
+ GC_FREE;
+}
+
int libxl_string_list_length(const libxl_string_list *psl)
{
int i = 0;
@@ -245,6 +268,34 @@ void libxl_key_value_list_dispose(libxl_key_value_list *pkvl)
free(kvl);
}
+void libxl_key_value_list_copy(libxl_ctx *ctx,
+ libxl_key_value_list *dst,
+ libxl_key_value_list *src)
+{
+ GC_INIT(ctx);
+ int i, len;
+
+ if (*src == NULL) {
+ *dst = NULL;
+ goto out;
+ }
+
+ len = libxl_key_value_list_length(src);
+ /* one extra slot for sentinel */
+ *dst = libxl__calloc(NOGC, len * 2 + 1, sizeof(char *));
+
+ for (i = 0; i < len * 2; i += 2) {
+ (*dst)[i] = libxl__strdup(NOGC, (*src)[i]);
+ if ((*src)[i+1])
+ (*dst)[i+1] = libxl__strdup(NOGC, (*src)[i+1]);
+ else
+ (*dst)[i+1] = NULL;
+ }
+
+out:
+ GC_FREE;
+}
+
void libxl_defbool_set(libxl_defbool *db, bool b)
{
db->val = b ? LIBXL__DEFBOOL_TRUE : LIBXL__DEFBOOL_FALSE;
@@ -5692,6 +5743,22 @@ int libxl_fd_set_cloexec(libxl_ctx *ctx, int fd, int cloexec)
int libxl_fd_set_nonblock(libxl_ctx *ctx, int fd, int nonblock)
{ return fd_set_flags(ctx,fd, F_GETFL,F_SETFL,"FL", O_NONBLOCK, nonblock); }
+
+void libxl_hwcap_copy(libxl_ctx *ctx,libxl_hwcap *dst, libxl_hwcap *src)
+{
+ int i;
+
+ for (i = 0; i < 8; i++)
+ (*dst)[i] = (*src)[i];
+}
+
+void libxl_mac_copy(libxl_ctx *ctx, libxl_mac *dst, libxl_mac *src)
+{
+ int i;
+
+ for (i = 0; i < 6; i++)
+ (*dst)[i] = (*src)[i];
+}
/*
* Local variables:
* mode: C
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index e52a43f..1fb365d 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -542,20 +542,29 @@ typedef struct libxl__ctx libxl_ctx;
*/
#define LIBXL_HAVE_CPUPOOL_NAME 1
+typedef struct libxl__ctx libxl_ctx;
+
typedef uint8_t libxl_mac[6];
#define LIBXL_MAC_FMT "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx"
#define LIBXL_MAC_FMTLEN ((2*6)+5) /* 6 hex bytes plus 5 colons */
#define LIBXL_MAC_BYTES(mac) mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]
+void libxl_mac_copy(libxl_ctx *ctx, libxl_mac *dst, libxl_mac *src);
typedef char **libxl_string_list;
void libxl_string_list_dispose(libxl_string_list *sl);
int libxl_string_list_length(const libxl_string_list *sl);
+void libxl_string_list_copy(libxl_ctx *ctx, libxl_string_list *dst,
+ libxl_string_list *src);
typedef char **libxl_key_value_list;
void libxl_key_value_list_dispose(libxl_key_value_list *kvl);
int libxl_key_value_list_length(libxl_key_value_list *kvl);
+void libxl_key_value_list_copy(libxl_ctx *ctx,
+ libxl_key_value_list *dst,
+ libxl_key_value_list *src);
typedef uint32_t libxl_hwcap[8];
+void libxl_hwcap_copy(libxl_ctx *ctx, libxl_hwcap *dst, libxl_hwcap *src);
typedef uint64_t libxl_ev_user;
@@ -574,6 +583,9 @@ typedef struct libxl__cpuid_policy libxl_cpuid_policy;
typedef libxl_cpuid_policy * libxl_cpuid_policy_list;
void libxl_cpuid_dispose(libxl_cpuid_policy_list *cpuid_list);
int libxl_cpuid_policy_list_length(libxl_cpuid_policy_list *l);
+void libxl_cpuid_policy_list_copy(libxl_ctx *ctx,
+ libxl_cpuid_policy_list *dst,
+ libxl_cpuid_policy_list *src);
#define LIBXL_PCI_FUNC_ALL (~0U)
diff --git a/tools/libxl/libxl_cpuid.c b/tools/libxl/libxl_cpuid.c
index 30c9ec3..6fa00be 100644
--- a/tools/libxl/libxl_cpuid.c
+++ b/tools/libxl/libxl_cpuid.c
@@ -468,6 +468,39 @@ int libxl_cpuid_policy_list_length(libxl_cpuid_policy_list *pl)
return i;
}
+void libxl_cpuid_policy_list_copy(libxl_ctx *ctx,
+ libxl_cpuid_policy_list *dst,
+ libxl_cpuid_policy_list *src)
+{
+ GC_INIT(ctx);
+ int i, j, len;
+
+ if (*src == NULL) {
+ *dst = NULL;
+ goto out;
+ }
+
+ len = libxl_cpuid_policy_list_length(src);
+ /* one extra slot for sentinel */
+ *dst = libxl__calloc(NOGC, len + 1, sizeof(libxl_cpuid_policy));
+ (*dst)[len].input[0] = XEN_CPUID_INPUT_UNUSED;
+ (*dst)[len].input[1] = XEN_CPUID_INPUT_UNUSED;
+
+ for (i = 0; i < len; i++) {
+ for (j = 0; j < 2; j++)
+ (*dst)[i].input[j] = (*src)[i].input[j];
+ for (j = 0; j < 4; j++)
+ if ((*src)[i].policy[j])
+ (*dst)[i].policy[j] =
+ libxl__strdup(NOGC, (*src)[i].policy[j]);
+ else
+ (*dst)[i].policy[j] = NULL;
+ }
+
+out:
+ GC_FREE;
+}
+
/*
* Local variables:
* mode: C
diff --git a/tools/libxl/libxl_nocpuid.c b/tools/libxl/libxl_nocpuid.c
index e98906a..8b567d0 100644
--- a/tools/libxl/libxl_nocpuid.c
+++ b/tools/libxl/libxl_nocpuid.c
@@ -51,6 +51,12 @@ int libxl__cpuid_policy_list_parse_json(libxl__gc *gc,
return 0;
}
+void libxl_cpuid_policy_list_copy(libxl_ctx *ctx,
+ libxl_cpuid_policy_list *dst,
+ libxl_cpuid_policy_list *src)
+{
+}
+
/*
* Local variables:
* mode: C
diff --git a/tools/libxl/libxl_utils.c b/tools/libxl/libxl_utils.c
index 16b734e..6053017 100644
--- a/tools/libxl/libxl_utils.c
+++ b/tools/libxl/libxl_utils.c
@@ -614,6 +614,19 @@ void libxl_bitmap_copy(libxl_ctx *ctx, libxl_bitmap *dptr,
memcpy(dptr->map, sptr->map, sz * sizeof(*dptr->map));
}
+void libxl_bitmap_copy_alloc(libxl_ctx *ctx,
+ libxl_bitmap *dptr,
+ const libxl_bitmap *sptr)
+{
+ GC_INIT(ctx);
+
+ dptr->map = libxl__calloc(NOGC, sptr->size, sizeof(*sptr->map));
+ dptr->size = sptr->size;
+ memcpy(dptr->map, sptr->map, sptr->size * sizeof(*sptr->map));
+
+ GC_FREE;
+}
+
int libxl_bitmap_is_full(const libxl_bitmap *bitmap)
{
int i;
@@ -1013,6 +1026,18 @@ int libxl_domid_valid_guest(uint32_t domid)
return domid > 0 && domid < DOMID_FIRST_RESERVED;
}
+void libxl_string_copy(libxl_ctx *ctx, char **dst, char **src)
+{
+ GC_INIT(ctx);
+
+ if (*src)
+ *dst = libxl__strdup(NOGC, *src);
+ else
+ *dst = NULL;
+
+ GC_FREE;
+}
+
/*
* Local variables:
* mode: C
diff --git a/tools/libxl/libxl_utils.h b/tools/libxl/libxl_utils.h
index 8bfb81b..cc528d2 100644
--- a/tools/libxl/libxl_utils.h
+++ b/tools/libxl/libxl_utils.h
@@ -76,6 +76,8 @@ int libxl_devid_to_device_vtpm(libxl_ctx *ctx, uint32_t domid,
int libxl_bitmap_alloc(libxl_ctx *ctx, libxl_bitmap *bitmap, int n_bits);
/* Allocated bimap is from malloc, libxl_bitmap_dispose() to be
* called by the application when done. */
+void libxl_bitmap_copy_alloc(libxl_ctx *ctx, libxl_bitmap *dptr,
+ const libxl_bitmap *sptr);
void libxl_bitmap_copy(libxl_ctx *ctx, libxl_bitmap *dptr,
const libxl_bitmap *sptr);
int libxl_bitmap_is_full(const libxl_bitmap *bitmap);
@@ -121,6 +123,8 @@ int libxl_cpumap_to_nodemap(libxl_ctx *ctx,
return (s + 1023) / 1024;
}
+void libxl_string_copy(libxl_ctx *ctx, char **dst, char **src);
+
#endif
/*
--
1.7.10.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v8 7/8] libxl IDL: generate deep copy functions
2014-06-19 17:44 [PATCH v8 0/8] libxl: JSON infrastructure Wei Liu
` (5 preceding siblings ...)
2014-06-19 17:44 ` [PATCH v8 6/8] libxl: copy function for builtin types Wei Liu
@ 2014-06-19 17:44 ` Wei Liu
2014-06-19 17:44 ` [PATCH v8 8/8] libxl/gentest.py: test " Wei Liu
7 siblings, 0 replies; 14+ messages in thread
From: Wei Liu @ 2014-06-19 17:44 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
Introduces copy_fn for a type.
For most builtin types we can use direct assignment. For those builtin
types which cannot use direct assignment we use the copy functions in
previous patch.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
tools/libxl/gentypes.py | 67 ++++++++++++++++++++++++++++++++++
tools/libxl/idl.py | 13 ++++++-
tools/libxl/idl.txt | 12 ++++++
tools/libxl/libxl_types.idl | 27 ++++++++------
tools/libxl/libxl_types_internal.idl | 2 +-
5 files changed, 108 insertions(+), 13 deletions(-)
diff --git a/tools/libxl/gentypes.py b/tools/libxl/gentypes.py
index 6cdeaa8..4b0c996 100644
--- a/tools/libxl/gentypes.py
+++ b/tools/libxl/gentypes.py
@@ -100,6 +100,61 @@ def libxl_C_type_dispose(ty, v, indent = " ", parent = None):
s = indent + s
return s.replace("\n", "\n%s" % indent).rstrip(indent)
+def libxl_C_type_copy(ty, v, w, indent = " ", vparent = None, wparent = None):
+ s = ""
+
+ if vparent is None:
+ s += "GC_INIT(ctx);\n";
+
+ if isinstance(ty, idl.KeyedUnion):
+ if vparent is None or wparent is None:
+ raise Exception("KeyedUnion type must have a parent")
+ s += "%s = %s;\n" % ((vparent + ty.keyvar.name), (wparent + ty.keyvar.name))
+ s += "switch (%s) {\n" % (wparent + ty.keyvar.name)
+ for f in ty.fields:
+ (vnparent,vfexpr) = ty.member(v, f, vparent is None)
+ (wnparent,wfexpr) = ty.member(w, f, wparent is None)
+ s += "case %s:\n" % f.enumname
+ if f.type is not None:
+ s += libxl_C_type_copy(f.type, vfexpr, wfexpr, indent + " ",
+ vnparent, wnparent)
+ s += " break;\n"
+ s += "}\n"
+ elif isinstance(ty, idl.Array):
+ if vparent is None or wparent is None:
+ raise Exception("Array type must have a parent")
+ s += "%s = libxl__calloc(NOGC, %s, sizeof(*%s));\n" % (ty.pass_arg(v, vparent is None),
+ (wparent + ty.lenvar.name),
+ ty.pass_arg(w, wparent is None))
+ s += "%s = %s;\n" % ((vparent + ty.lenvar.name), (wparent + ty.lenvar.name))
+ s += "{\n"
+ s += " int i;\n"
+ s += " for (i=0; i<%s; i++)\n" % (wparent + ty.lenvar.name)
+ s += libxl_C_type_copy(ty.elem_type, v+"[i]", w+"[i]",
+ indent + " ", vparent, wparent)
+ s += "}\n"
+ elif isinstance(ty, idl.Struct) and ((vparent is None and wparent is None) or ty.copy_fn is None):
+ for f in [f for f in ty.fields if not f.const and not f.type.private]:
+ (vnparent,vfexpr) = ty.member(v, f, vparent is None)
+ (wnparent,wfexpr) = ty.member(w, f, wparent is None)
+ s += libxl_C_type_copy(f.type, vfexpr, wfexpr, "", vnparent, wnparent)
+ else:
+ if ty.copy_fn is not None:
+ s += "%s(ctx, %s, %s);\n" % (ty.copy_fn,
+ ty.pass_arg(v, vparent is None, passby=idl.PASS_BY_REFERENCE),
+ ty.pass_arg(w, wparent is None, passby=idl.PASS_BY_REFERENCE))
+
+ else:
+ s += "%s = %s;\n" % (ty.pass_arg(v, vparent is None, passby=idl.PASS_BY_VALUE),
+ ty.pass_arg(w, wparent is None, passby=idl.PASS_BY_VALUE))
+
+ if vparent is None:
+ s += "GC_FREE;\n"
+
+ if s != "":
+ s = indent + s
+ return s.replace("\n", "\n%s" % indent).rstrip(indent)
+
def libxl_init_members(ty, nesting = 0):
"""Returns a list of members of ty which require a separate init"""
@@ -489,6 +544,9 @@ if __name__ == '__main__':
f.write(libxl_C_type_define(ty) + ";\n")
if ty.dispose_fn is not None:
f.write("%svoid %s(%s);\n" % (ty.hidden(), ty.dispose_fn, ty.make_arg("p")))
+ if ty.copy_fn is not None:
+ f.write("%svoid %s(libxl_ctx *ctx, %s, %s);\n" % (ty.hidden(), ty.copy_fn,
+ ty.make_arg("dst"), ty.make_arg("src")))
if ty.init_fn is not None:
f.write("%svoid %s(%s);\n" % (ty.hidden(), ty.init_fn, ty.make_arg("p")))
for field in libxl_init_members(ty):
@@ -590,6 +648,15 @@ if __name__ == '__main__':
f.write(" memset(p, LIBXL_DTOR_POISON, sizeof(*p));\n")
f.write("}\n")
f.write("\n")
+
+ for ty in [t for t in types if t.copy_fn and t.autogenerate_copy_fn]:
+ f.write("void %s(libxl_ctx *ctx, %s, %s)\n" % (ty.copy_fn,
+ ty.make_arg("dst", passby=idl.PASS_BY_REFERENCE),
+ ty.make_arg("src", passby=idl.PASS_BY_REFERENCE)))
+ f.write("{\n")
+ f.write(libxl_C_type_copy(ty, "dst", "src"))
+ f.write("}\n")
+ f.write("\n")
for ty in [t for t in types if t.init_fn is not None and t.autogenerate_init_fn]:
f.write(libxl_C_type_init(ty))
diff --git a/tools/libxl/idl.py b/tools/libxl/idl.py
index 63557db..437049e 100644
--- a/tools/libxl/idl.py
+++ b/tools/libxl/idl.py
@@ -60,6 +60,13 @@ class Type(object):
self.autogenerate_dispose_fn = kwargs.setdefault('autogenerate_dispose_fn', True)
+ if self.typename is not None:
+ self.copy_fn = kwargs.setdefault('copy_fn', self.typename + "_copy")
+ else:
+ self.copy_fn = kwargs.setdefault('copy_fn', None)
+
+ self.autogenerate_copy_fn = kwargs.setdefault('autogenerate_copy_fn', True)
+
self.init_fn = kwargs.setdefault('init_fn', None)
self.init_val = kwargs.setdefault('init_val', None)
self.autogenerate_init_fn = kwargs.setdefault('autogenerate_init_fn', False)
@@ -128,6 +135,7 @@ class Number(Builtin):
def __init__(self, ctype, **kwargs):
kwargs.setdefault('namespace', None)
kwargs.setdefault('dispose_fn', None)
+ kwargs.setdefault('copy_fn', None)
kwargs.setdefault('signed', False)
kwargs.setdefault('json_gen_fn', "yajl_gen_integer")
kwargs.setdefault('json_parse_type', "JSON_INTEGER")
@@ -141,6 +149,7 @@ class UInt(Number):
kwargs.setdefault('namespace', None)
kwargs.setdefault('dispose_fn', None)
kwargs.setdefault('json_parse_fn', "libxl__uint%d_parse_json" % w)
+ kwargs.setdefault('copy_fn', None)
Number.__init__(self, "uint%d_t" % w, **kwargs)
self.width = w
@@ -157,6 +166,7 @@ class EnumerationValue(object):
class Enumeration(Type):
def __init__(self, typename, values, **kwargs):
kwargs.setdefault('dispose_fn', None)
+ kwargs.setdefault('copy_fn', None)
kwargs.setdefault('json_parse_type', "JSON_STRING")
Type.__init__(self, typename, **kwargs)
@@ -273,6 +283,7 @@ class KeyedUnion(Aggregate):
void = Builtin("void *", namespace = None)
bool = Builtin("bool", namespace = None,
+ copy_fn=None,
json_gen_fn = "yajl_gen_bool",
json_parse_type = "JSON_BOOL",
json_parse_fn = "libxl__bool_parse_json",
@@ -287,7 +298,7 @@ uint16 = UInt(16)
uint32 = UInt(32)
uint64 = UInt(64, json_gen_fn = "libxl__uint64_gen_json")
-string = Builtin("char *", namespace = None, dispose_fn = "free",
+string = Builtin("char *", namespace = None, copy_fn = "libxl_string_copy", dispose_fn = "free",
json_gen_fn = "libxl__string_gen_json",
json_parse_type = "JSON_STRING | JSON_NULL",
json_parse_fn = "libxl__string_parse_json",
diff --git a/tools/libxl/idl.txt b/tools/libxl/idl.txt
index 87c4952..7440fb3 100644
--- a/tools/libxl/idl.txt
+++ b/tools/libxl/idl.txt
@@ -44,6 +44,18 @@ Type.autogenerate_dispose_fn: (default: True)
Indicates if the above named Type.dispose_fn should be
autogenerated.
+Type.copy_fn: (default: typename + "_copy" or None if type == None)
+
+ The name of the C function which will deep copy all fields within
+ this type.
+
+Type.autogenerate_copy_fn: (default: True)
+
+ Indicates if the above named Type.copy_fn should be
+ autogenerated.
+
+Type.autogenerate_copy_fn
+
Type.init_val: (default: None)
C expression for the value to initialise instances of this type to.
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index 2cb856c..d40b5c7 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -5,26 +5,31 @@
namespace("libxl_")
-libxl_defbool = Builtin("defbool", json_parse_type="JSON_STRING", passby=PASS_BY_REFERENCE,
+libxl_defbool = Builtin("defbool", json_parse_type="JSON_STRING", passby=PASS_BY_REFERENCE, copy_fn=None,
check_default_fn="libxl__defbool_is_default")
-
libxl_domid = Builtin("domid", json_gen_fn = "yajl_gen_integer", json_parse_fn = "libxl__uint32_parse_json",
- json_parse_type = "JSON_INTEGER", autogenerate_json = False)
+ json_parse_type = "JSON_INTEGER", autogenerate_json = False, copy_fn=None)
libxl_devid = Builtin("devid", json_gen_fn = "yajl_gen_integer", json_parse_fn = "libxl__int_parse_json",
- json_parse_type = "JSON_INTEGER", autogenerate_json = False, signed = True, init_val="-1")
-libxl_uuid = Builtin("uuid", json_parse_type="JSON_STRING", passby=PASS_BY_REFERENCE, check_default_fn="libxl_uuid_is_nil")
-libxl_mac = Builtin("mac", json_parse_type="JSON_STRING", passby=PASS_BY_REFERENCE, check_default_fn="libxl__mac_is_default")
+ json_parse_type = "JSON_INTEGER", autogenerate_json = False, signed = True, init_val="-1",
+ copy_fn=None)
+libxl_uuid = Builtin("uuid", json_parse_type="JSON_STRING", passby=PASS_BY_REFERENCE, check_default_fn="libxl_uuid_is_nil",
+ copy_fn="libxl_uuid_copy")
+libxl_mac = Builtin("mac", json_parse_type="JSON_STRING", passby=PASS_BY_REFERENCE, check_default_fn="libxl__mac_is_default",
+ copy_fn="libxl_mac_copy")
libxl_bitmap = Builtin("bitmap", json_parse_type="JSON_ARRAY", dispose_fn="libxl_bitmap_dispose", passby=PASS_BY_REFERENCE,
- check_default_fn="libxl_bitmap_is_empty")
+ check_default_fn="libxl_bitmap_is_empty", copy_fn="libxl_bitmap_copy_alloc")
libxl_cpuid_policy_list = Builtin("cpuid_policy_list", dispose_fn="libxl_cpuid_dispose", passby=PASS_BY_REFERENCE,
- json_parse_type="JSON_ARRAY", check_default_fn="libxl__cpuid_policy_is_empty")
+ json_parse_type="JSON_ARRAY", check_default_fn="libxl__cpuid_policy_is_empty",
+ copy_fn="libxl_cpuid_policy_list_copy")
libxl_string_list = Builtin("string_list", dispose_fn="libxl_string_list_dispose", passby=PASS_BY_REFERENCE,
- json_parse_type="JSON_ARRAY", check_default_fn="libxl__string_list_is_empty")
+ json_parse_type="JSON_ARRAY", check_default_fn="libxl__string_list_is_empty",
+ copy_fn="libxl_string_list_copy")
libxl_key_value_list = Builtin("key_value_list", dispose_fn="libxl_key_value_list_dispose", passby=PASS_BY_REFERENCE,
- json_parse_type="JSON_MAP", check_default_fn="libxl__key_value_list_is_empty")
+ json_parse_type="JSON_MAP", check_default_fn="libxl__key_value_list_is_empty",
+ copy_fn="libxl_key_value_list_copy")
libxl_hwcap = Builtin("hwcap", passby=PASS_BY_REFERENCE, json_parse_type="JSON_ARRAY",
- check_default_fn="libxl__hwcap_is_default")
+ check_default_fn="libxl__hwcap_is_default", copy_fn="libxl_hwcap_copy")
#
# Specific integer types
diff --git a/tools/libxl/libxl_types_internal.idl b/tools/libxl/libxl_types_internal.idl
index 17533f1..800361b 100644
--- a/tools/libxl/libxl_types_internal.idl
+++ b/tools/libxl/libxl_types_internal.idl
@@ -3,7 +3,7 @@ hidden(True)
libxl_domid = Builtin("domid", namespace="libxl_", json_gen_fn = "yajl_gen_integer",
json_parse_fn = "libxl__uint32_parse_json", json_parse_type = "JSON_INTEGER",
- autogenerate_json = False)
+ autogenerate_json = False, copy_fn = None)
libxl__qmp_message_type = Enumeration("qmp_message_type", [
(1, "QMP"),
--
1.7.10.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v8 8/8] libxl/gentest.py: test deep copy functions
2014-06-19 17:44 [PATCH v8 0/8] libxl: JSON infrastructure Wei Liu
` (6 preceding siblings ...)
2014-06-19 17:44 ` [PATCH v8 7/8] libxl IDL: generate deep copy functions Wei Liu
@ 2014-06-19 17:44 ` Wei Liu
7 siblings, 0 replies; 14+ messages in thread
From: Wei Liu @ 2014-06-19 17:44 UTC (permalink / raw)
To: xen-devel; +Cc: Wei Liu, ian.jackson, ian.campbell
The test is done as followed:
1. initialise libxl_FOO struct A
2. deep-copy A to B
3. generate JSON string for A and B
4. compare two JSON strings
If two strings are identical then we're good.
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
tools/libxl/gentest.py | 37 +++++++++++++++++++++++++++++++++++++
1 file changed, 37 insertions(+)
diff --git a/tools/libxl/gentest.py b/tools/libxl/gentest.py
index b92d092..07ffd31 100644
--- a/tools/libxl/gentest.py
+++ b/tools/libxl/gentest.py
@@ -273,6 +273,43 @@ int main(int argc, char **argv)
f.write(" %s(&%s_val_new);\n" % (ty.dispose_fn, ty.typename))
f.write("\n")
+ f.write(" printf(\"Testing TYPE_copy()\\n\");\n")
+ f.write(" printf(\"----------------------\\n\");\n")
+ f.write(" printf(\"\\n\");\n")
+ for ty in [t for t in types if t.copy_fn is not None]:
+ f.write(" printf(\"Testing %s_copy, \");\n" % ty.typename)
+ arg = ty.typename + "_val"
+ f.write(" %s_init(%s);\n" % (ty.typename, \
+ ty.pass_arg(arg, isref=False, passby=idl.PASS_BY_REFERENCE)))
+ f.write(" %s_rand_init(%s);\n" % (ty.typename, \
+ ty.pass_arg(arg, isref=False, passby=idl.PASS_BY_REFERENCE)))
+ f.write(" %s_init(%s_new);\n" % (ty.typename, \
+ ty.pass_arg(arg, isref=False, passby=idl.PASS_BY_REFERENCE)))
+ f.write(" %s_copy(ctx, %s_new, %s);\n" % (ty.typename, \
+ ty.pass_arg(arg, isref=False, passby=idl.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(" if (s == NULL) abort();\n")
+ f.write(" new_s = %s_to_json(ctx, %s_new);\n" % \
+ (ty.typename, ty.pass_arg(arg, isref=False)))
+ f.write(" if (new_s == NULL) abort();\n")
+ f.write(" if (strcmp(s, new_s)) {\n")
+ f.write(" printf(\"Huh? Deep copy for %s failed. Regenerated string different from original string.\\n\");\n" \
+ % ty.typename)
+ f.write(" printf(\"Original string: %s\\n\", s);\n")
+ f.write(" printf(\"Regenerated string: %s\\n\", new_s);\n")
+ f.write(" abort();\n")
+ f.write(" }\n")
+ f.write(" free(s);\n")
+ f.write(" free(new_s);\n")
+ if ty.dispose_fn is not None:
+ f.write(" %s(&%s_val);\n" % (ty.dispose_fn, ty.typename))
+ f.write(" %s(&%s_val_new);\n" % (ty.dispose_fn, ty.typename))
+ f.write(" printf(\"done\\n\");\n")
+ f.write("\n")
+
+ f.write(" printf(\"\\n\");\n")
f.write(" printf(\"Testing Enumerations\\n\");\n")
f.write(" printf(\"--------------------\\n\");\n")
f.write(" printf(\"\\n\");\n")
--
1.7.10.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH v8 1/8] libxl_internal: functions to check default values for builtin types
2014-06-19 17:44 ` [PATCH v8 1/8] libxl_internal: functions to check default values for builtin types Wei Liu
@ 2014-06-27 11:36 ` Ian Campbell
0 siblings, 0 replies; 14+ messages in thread
From: Ian Campbell @ 2014-06-27 11:36 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, xen-devel
On Thu, 2014-06-19 at 18:44 +0100, Wei Liu wrote:
> They will be used in later patch to determine whether we should generate
> JSON output for a type. If that type has default value we just skip
> generating JSON output.
>
> Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v8 2/8] libxl/gentypes.py: don't generate default values
2014-06-19 17:44 ` [PATCH v8 2/8] libxl/gentypes.py: don't generate default values Wei Liu
@ 2014-06-27 11:37 ` Ian Campbell
2014-07-09 8:53 ` Wei Liu
0 siblings, 1 reply; 14+ messages in thread
From: Ian Campbell @ 2014-06-27 11:37 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, xen-devel
On Thu, 2014-06-19 at 18:44 +0100, Wei Liu wrote:
Unfortunately there was a conflict in libxl_types.idl against David's
addition of the generation id type. The reject itself was trivial but I
think the addition of that type means you need a check_default_fn for
it.
Sorry.
Ian.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v8 3/8] libxl: clean up namespace violation
2014-06-19 17:44 ` [PATCH v8 3/8] libxl: clean up namespace violation Wei Liu
@ 2014-06-27 11:37 ` Ian Campbell
0 siblings, 0 replies; 14+ messages in thread
From: Ian Campbell @ 2014-06-27 11:37 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, xen-devel
On Thu, 2014-06-19 at 18:44 +0100, Wei Liu wrote:
> In 752f181f ("libxl_json: introduce parser functions for builtin types")
> a bunch of parser functions were introduced. Unfortunately they
> polluted the public namespace with a prefix "libxl_", while they should
> be internal functions.
>
> This patch changes the prefix to "libxl__". No functional change
> introduced.
>
> Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v8 4/8] libxl IDL: generate code to parse libxl__json_object to libxl_FOO struct
2014-06-19 17:44 ` [PATCH v8 4/8] libxl IDL: generate code to parse libxl__json_object to libxl_FOO struct Wei Liu
@ 2014-06-27 11:40 ` Ian Campbell
0 siblings, 0 replies; 14+ messages in thread
From: Ian Campbell @ 2014-06-27 11:40 UTC (permalink / raw)
To: Wei Liu; +Cc: ian.jackson, xen-devel
On Thu, 2014-06-19 at 18:44 +0100, Wei Liu wrote:
> libxl_FOO_parse_json functions are generated.
>
> Note that these functions are used to parse libxl__json_object to
> libxl__FOO struct. They don't consume JSON string.
>
> The new function definitions are generated to new header files called
> __libxl_types_*_private.h so that they don't contaminate public header.
> The suffix "private is chosen so we can avoid clashing with
> libxl_types_internal.idl stuffs.
>
> Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
But you should consider two things:
> diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile
> index 7fc42c8..b1ad8d4 100644
> --- a/tools/libxl/Makefile
> +++ b/tools/libxl/Makefile
> @@ -184,8 +184,10 @@ $(LIBXL_OBJS) $(LIBXL_TEST_OBJS) $(LIBXLU_OBJS) \
> $(LIBXL_OBJS) $(LIBXL_TEST_OBJS): libxl_internal.h
>
> _libxl_type%.h _libxl_type%_json.h _libxl_type%.c: libxl_type%.idl gentypes.py idl.py
Listing the new output file as a target here (before the :).
and whether you should be extending the existing:
libxl.h: _libxl_types.h
libxl_json.h: _libxl_types_json.h
libxl_internal.h: _libxl_types_internal.h _paths.h
libxl_internal_json.h: _libxl_types_internal_json.h
xl.h: _paths.h
To declare the new relationships from:
> diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
> index 9e8bc4c..a5803d2 100644
> --- a/tools/libxl/libxl_internal.h
> +++ b/tools/libxl/libxl_internal.h
> @@ -3186,6 +3186,9 @@ int libxl__uint64_parse_json(libxl__gc *gc, const libxl__json_object *o,
> int libxl__string_parse_json(libxl__gc *gc, const libxl__json_object *o,
> char **p);
>
> +#include "_libxl_types_private.h"
> +#include "_libxl_types_internal_private.h"
> +
> /* This always return false, there's no "default value" for hw cap */
> static inline int libxl__hwcap_is_default(libxl_hwcap *hwcap)
> {
Ian.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v8 2/8] libxl/gentypes.py: don't generate default values
2014-06-27 11:37 ` Ian Campbell
@ 2014-07-09 8:53 ` Wei Liu
0 siblings, 0 replies; 14+ messages in thread
From: Wei Liu @ 2014-07-09 8:53 UTC (permalink / raw)
To: Ian Campbell; +Cc: ian.jackson, Wei Liu, xen-devel
On Fri, Jun 27, 2014 at 12:37:11PM +0100, Ian Campbell wrote:
> On Thu, 2014-06-19 at 18:44 +0100, Wei Liu wrote:
>
> Unfortunately there was a conflict in libxl_types.idl against David's
> addition of the generation id type. The reject itself was trivial but I
> think the addition of that type means you need a check_default_fn for
> it.
>
David already provided a function called libxl_ms_vm_genid_is_zero, I
will use it in my patch.
Wei.
> Sorry.
>
> Ian.
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2014-07-09 8:53 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-06-19 17:44 [PATCH v8 0/8] libxl: JSON infrastructure Wei Liu
2014-06-19 17:44 ` [PATCH v8 1/8] libxl_internal: functions to check default values for builtin types Wei Liu
2014-06-27 11:36 ` Ian Campbell
2014-06-19 17:44 ` [PATCH v8 2/8] libxl/gentypes.py: don't generate default values Wei Liu
2014-06-27 11:37 ` Ian Campbell
2014-07-09 8:53 ` Wei Liu
2014-06-19 17:44 ` [PATCH v8 3/8] libxl: clean up namespace violation Wei Liu
2014-06-27 11:37 ` Ian Campbell
2014-06-19 17:44 ` [PATCH v8 4/8] libxl IDL: generate code to parse libxl__json_object to libxl_FOO struct Wei Liu
2014-06-27 11:40 ` Ian Campbell
2014-06-19 17:44 ` [PATCH v8 5/8] libxl/gentest.py: test JSON parser Wei Liu
2014-06-19 17:44 ` [PATCH v8 6/8] libxl: copy function for builtin types Wei Liu
2014-06-19 17:44 ` [PATCH v8 7/8] libxl IDL: generate deep copy functions Wei Liu
2014-06-19 17:44 ` [PATCH v8 8/8] libxl/gentest.py: test " Wei Liu
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.