WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH V8 6/7] libxl: Introduce JSON parsing stuff.

To: Xen Devel <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH V8 6/7] libxl: Introduce JSON parsing stuff.
From: Anthony PERARD <anthony.perard@xxxxxxxxxx>
Date: Tue, 26 Jul 2011 20:13:06 +0100
Cc: Ian Campbell <Ian.Campbell@xxxxxxxxxxxxx>, Anthony PERARD <anthony.perard@xxxxxxxxxx>, Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
Delivery-date: Tue, 26 Jul 2011 12:23:05 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <1311707587-6686-1-git-send-email-anthony.perard@xxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <1311707587-6686-1-git-send-email-anthony.perard@xxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
We use the yajl parser, but we need to make a tree from the parse result
to use it outside the parser.

So this patch include json_object struct that is used to hold the JSON
data.

Signed-off-by: Anthony PERARD <anthony.perard@xxxxxxxxxx>
---
 README                       |    1 +
 tools/libxl/Makefile         |    5 +-
 tools/libxl/libxl_internal.h |  100 ++++++++
 tools/libxl/libxl_json.c     |  560 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 665 insertions(+), 1 deletions(-)
 create mode 100644 tools/libxl/libxl_json.c

diff --git a/README b/README
index ff154b2..c9bf699 100644
--- a/README
+++ b/README
@@ -47,6 +47,7 @@ provided by your OS distributor:
     * Development install of openssl (e.g., openssl-dev)
     * Development install of x11 (e.g. xorg-x11-dev)
     * Development install of uuid (e.g. uuid-dev)
+    * Development install of yajl (e.g. libyajl-dev)
     * bridge-utils package (/sbin/brctl)
     * iproute package (/sbin/ip)
     * hotplug or udev
diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile
index 1f6b418..e50874e 100644
--- a/tools/libxl/Makefile
+++ b/tools/libxl/Makefile
@@ -32,9 +32,12 @@ endif
 LIBXL_OBJS-$(CONFIG_X86) += libxl_cpuid.o
 LIBXL_OBJS-$(CONFIG_IA64) += libxl_nocpuid.o
 
+LIBXL_LIBS += -lyajl
+
 LIBXL_OBJS = flexarray.o libxl.o libxl_create.o libxl_dm.o libxl_pci.o \
                        libxl_dom.o libxl_exec.o libxl_xshelp.o libxl_device.o \
-                       libxl_internal.o libxl_utils.o libxl_uuid.o 
$(LIBXL_OBJS-y)
+                       libxl_internal.o libxl_utils.o libxl_uuid.o 
libxl_json.o \
+                       $(LIBXL_OBJS-y)
 LIBXL_OBJS += _libxl_types.o libxl_flask.o _libxl_types_internal.o
 
 $(LIBXL_OBJS): CFLAGS += $(CFLAGS_libxenctrl) $(CFLAGS_libxenguest) 
$(CFLAGS_libxenstore) $(CFLAGS_libblktapctl)
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index d873243..f495e86 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -387,4 +387,104 @@ _hidden int libxl__e820_alloc(libxl_ctx *ctx, uint32_t 
domid, libxl_domain_confi
 #define STRINGIFY(x) #x
 #define TOSTRING(x) STRINGIFY(x)
 
+/* from libxl_json */
+#include <yajl/yajl_gen.h>
+
+_hidden yajl_gen_status libxl__yajl_gen_asciiz(yajl_gen hand, const char *str);
+
+typedef enum {
+    JSON_ERROR,
+    JSON_NULL,
+    JSON_TRUE,
+    JSON_FALSE,
+    JSON_INTEGER,
+    JSON_DOUBLE,
+    JSON_STRING,
+    JSON_MAP,
+    JSON_ARRAY,
+    JSON_ANY
+} libxl__json_node_type;
+
+typedef struct libxl__json_object {
+    libxl__json_node_type type;
+    union {
+        long i;
+        double d;
+        char *string;
+        /* List of libxl__json_object */
+        flexarray_t *array;
+        /* List of libxl__json_map_node */
+        flexarray_t *map;
+    } u;
+    struct libxl__json_object *parent;
+} libxl__json_object;
+
+typedef struct {
+    char *map_key;
+    libxl__json_object *obj;
+} libxl__json_map_node;
+
+typedef struct libxl__yajl_ctx libxl__yajl_ctx;
+
+static inline bool libxl__json_object_is_string(const libxl__json_object *o)
+{
+    return o != NULL && o->type == JSON_STRING;
+}
+static inline bool libxl__json_object_is_integer(const libxl__json_object *o)
+{
+    return o != NULL && o->type == JSON_INTEGER;
+}
+static inline bool libxl__json_object_is_map(const libxl__json_object *o)
+{
+    return o != NULL && o->type == JSON_MAP;
+}
+static inline bool libxl__json_object_is_array(const libxl__json_object *o)
+{
+    return o != NULL && o->type == JSON_ARRAY;
+}
+
+static inline
+const char *libxl__json_object_get_string(const libxl__json_object *o)
+{
+    if (libxl__json_object_is_string(o))
+        return o->u.string;
+    else
+        return NULL;
+}
+static inline
+flexarray_t *libxl__json_object_get_map(const libxl__json_object *o)
+{
+    if (libxl__json_object_is_map(o))
+        return o->u.map;
+    else
+        return NULL;
+}
+static inline
+flexarray_t *libxl__json_object_get_array(const libxl__json_object *o)
+{
+    if (libxl__json_object_is_array(o))
+        return o->u.array;
+    else
+        return NULL;
+}
+static inline long libxl__json_object_get_integer(const libxl__json_object *o)
+{
+    if (libxl__json_object_is_integer(o))
+        return o->u.i;
+    else
+        return -1;
+}
+
+_hidden libxl__json_object *libxl__json_array_get(const libxl__json_object *o,
+                                                  int i);
+_hidden
+libxl__json_map_node *libxl__json_map_node_get(const libxl__json_object *o,
+                                               int i);
+_hidden const libxl__json_object *libxl__json_map_get(const char *key,
+                                          const libxl__json_object *o,
+                                          libxl__json_node_type expected_type);
+_hidden void libxl__json_object_free(libxl__gc *gc, libxl__json_object *obj);
+
+_hidden libxl__json_object *libxl__json_parse(libxl__gc *gc, const char *s);
+
 #endif
diff --git a/tools/libxl/libxl_json.c b/tools/libxl/libxl_json.c
new file mode 100644
index 0000000..e771925
--- /dev/null
+++ b/tools/libxl/libxl_json.c
@@ -0,0 +1,560 @@
+/*
+ * Copyright (C) 2011      Citrix Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 only. with the special
+ * exception on linking described in file LICENSE.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include <yajl/yajl_parse.h>
+#include <yajl/yajl_gen.h>
+
+#include "libxl_internal.h"
+
+/* #define DEBUG_ANSWER */
+
+struct libxl__yajl_ctx {
+    libxl__gc *gc;
+    yajl_handle hand;
+    libxl__json_object *head;
+    libxl__json_object *current;
+#ifdef DEBUG_ANSWER
+    yajl_gen g;
+#endif
+};
+
+#ifdef DEBUG_ANSWER
+#  define DEBUG_GEN_ALLOC(ctx) \
+    if ((ctx)->g == NULL) { \
+        yajl_gen_config conf = { 1, "  " }; \
+        (ctx)->g = yajl_gen_alloc(&conf, NULL); \
+    }
+#  define DEBUG_GEN_FREE(ctx) \
+    if ((ctx)->g) yajl_gen_free((ctx)->g)
+#  define DEBUG_GEN(ctx, type)              yajl_gen_##type(ctx->g)
+#  define DEBUG_GEN_VALUE(ctx, type, value) yajl_gen_##type(ctx->g, value)
+#  define DEBUG_GEN_STRING(ctx, str, n)     yajl_gen_string(ctx->g, str, n)
+#  define DEBUG_GEN_REPORT(yajl_ctx) \
+    do { \
+        const unsigned char *buf = NULL; \
+        unsigned int len = 0; \
+        yajl_gen_get_buf((yajl_ctx)->g, &buf, &len); \
+        LIBXL__LOG(libxl__gc_owner((yajl_ctx)->gc), \
+                   LIBXL__LOG_DEBUG, "response:\n%s", buf); \
+        yajl_gen_free((yajl_ctx)->g); \
+        (yajl_ctx)->g = NULL; \
+    } while (0)
+#else
+#  define DEBUG_GEN_ALLOC(ctx)                  ((void)0)
+#  define DEBUG_GEN_FREE(ctx)                   ((void)0)
+#  define DEBUG_GEN(ctx, type)                  ((void)0)
+#  define DEBUG_GEN_VALUE(ctx, type, value)     ((void)0)
+#  define DEBUG_GEN_STRING(ctx, value, lenght)  ((void)0)
+#  define DEBUG_GEN_REPORT(ctx)                 ((void)0)
+#endif
+
+/*
+ * YAJL Helper
+ */
+
+yajl_gen_status libxl__yajl_gen_asciiz(yajl_gen hand, const char *str)
+{
+    return yajl_gen_string(hand, (const unsigned char *)str, strlen(str));
+}
+
+
+/*
+ * libxl__json_object helper functions
+ */
+
+static libxl__json_object *json_object_alloc(libxl__gc *gc,
+                                             libxl__json_node_type type)
+{
+    libxl__json_object *obj;
+
+    obj = calloc(1, sizeof (libxl__json_object));
+    if (obj == NULL) {
+        LIBXL__LOG_ERRNO(libxl__gc_owner(gc), LIBXL__LOG_ERROR,
+                         "Failed to allocate a libxl__json_object");
+        return NULL;
+    }
+
+    obj->type = type;
+
+    if (type == JSON_MAP || type == JSON_ARRAY) {
+        flexarray_t *array = flexarray_make(1, 1);
+        if (array == NULL) {
+            LIBXL__LOG_ERRNO(libxl__gc_owner(gc), LIBXL__LOG_ERROR,
+                             "Failed to allocate a flexarray");
+            free(obj);
+            return NULL;
+        }
+        if (type == JSON_MAP)
+            obj->u.map = array;
+        else
+            obj->u.array = array;
+    }
+
+    return obj;
+}
+
+static int json_object_append_to(libxl__gc *gc,
+                                 libxl__json_object *obj,
+                                 libxl__json_object *dst)
+{
+    assert(dst != NULL);
+
+    switch (dst->type) {
+    case JSON_MAP: {
+        libxl__json_map_node *last;
+
+        if (dst->u.map->count == 0) {
+            LIBXL__LOG(libxl__gc_owner(gc), LIBXL__LOG_ERROR,
+                       "Try to add a value to an empty map (with no key)");
+            return -1;
+        }
+        flexarray_get(dst->u.map, dst->u.map->count - 1, (void**)&last);
+        last->obj = obj;
+        break;
+    }
+    case JSON_ARRAY:
+        if (flexarray_append(dst->u.array, obj) == 2) {
+            LIBXL__LOG_ERRNO(libxl__gc_owner(gc), LIBXL__LOG_ERROR,
+                             "Failed to grow a flexarray");
+            return -1;
+        }
+        break;
+    default:
+        LIBXL__LOG(libxl__gc_owner(gc), LIBXL__LOG_ERROR,
+                   "Try append an object is not a map/array (%i)\n",
+                   dst->type);
+        return -1;
+    }
+
+    obj->parent = dst;
+    return 0;
+}
+
+void libxl__json_object_free(libxl__gc *gc, libxl__json_object *obj)
+{
+    int index = 0;
+
+    if (obj == NULL)
+        return;
+    switch (obj->type) {
+    case JSON_STRING:
+        free(obj->u.string);
+        break;
+    case JSON_MAP: {
+        libxl__json_map_node *node = NULL;
+
+        for (index = 0; index < obj->u.map->count; index++) {
+            if (flexarray_get(obj->u.map, index, (void**)&node) != 0)
+                break;
+            libxl__json_object_free(gc, node->obj);
+            free(node->map_key);
+            free(node);
+            node = NULL;
+        }
+        flexarray_free(obj->u.map);
+        break;
+    }
+    case JSON_ARRAY: {
+        libxl__json_object *node = NULL;
+        break;
+
+        for (index = 0; index < obj->u.array->count; index++) {
+            if (flexarray_get(obj->u.array, index, (void**)&node) != 0)
+                break;
+            libxl__json_object_free(gc, node);
+            node = NULL;
+        }
+        flexarray_free(obj->u.array);
+        break;
+    }
+    default:
+        break;
+    }
+    free(obj);
+}
+
+libxl__json_object *libxl__json_array_get(const libxl__json_object *o, int i)
+{
+    flexarray_t *array = NULL;
+    libxl__json_object *obj = NULL;
+
+    if ((array = libxl__json_object_get_array(o)) == NULL) {
+        return NULL;
+    }
+
+    if (i >= array->count)
+        return NULL;
+
+    if (flexarray_get(array, i, (void**)&obj) != 0)
+        return NULL;
+
+    return obj;
+}
+
+libxl__json_map_node *libxl__json_map_node_get(const libxl__json_object *o,
+                                               int i)
+{
+    flexarray_t *array = NULL;
+    libxl__json_map_node *obj = NULL;
+
+    if ((array = libxl__json_object_get_map(o)) == NULL) {
+        return NULL;
+    }
+
+    if (i >= array->count)
+        return NULL;
+
+    if (flexarray_get(array, i, (void**)&obj) != 0)
+        return NULL;
+
+    return obj;
+}
+
+const libxl__json_object *libxl__json_map_get(const char *key,
+                                          const libxl__json_object *o,
+                                          libxl__json_node_type expected_type)
+{
+    flexarray_t *maps = NULL;
+    int index = 0;
+
+    if (libxl__json_object_is_map(o)) {
+        libxl__json_map_node *node = NULL;
+
+        maps = o->u.map;
+        for (index = 0; index < maps->count; index++) {
+            if (flexarray_get(maps, index, (void**)&node) != 0)
+                return NULL;
+            if (strcmp(key, node->map_key) == 0) {
+                if (expected_type == JSON_ANY
+                    || (node->obj && node->obj->type == expected_type)) {
+                    return node->obj;
+                } else {
+                    return NULL;
+                }
+            }
+        }
+    }
+    return NULL;
+}
+
+
+/*
+ * JSON callbacks
+ */
+
+static int json_callback_null(void *opaque)
+{
+    libxl__yajl_ctx *ctx = opaque;
+    libxl__json_object *obj;
+
+    DEBUG_GEN(ctx, null);
+
+    if ((obj = json_object_alloc(ctx->gc, JSON_NULL)) == NULL)
+        return 0;
+
+    if (json_object_append_to(ctx->gc, obj, ctx->current) == -1) {
+        libxl__json_object_free(ctx->gc, obj);
+        return 0;
+    }
+
+    return 1;
+}
+
+static int json_callback_boolean(void *opaque, int boolean)
+{
+    libxl__yajl_ctx *ctx = opaque;
+    libxl__json_object *obj;
+
+    DEBUG_GEN_VALUE(ctx, bool, boolean);
+
+    if ((obj = json_object_alloc(ctx->gc,
+                                 boolean ? JSON_TRUE : JSON_FALSE)) == NULL)
+        return 0;
+
+    if (json_object_append_to(ctx->gc, obj, ctx->current) == -1) {
+        libxl__json_object_free(ctx->gc, obj);
+        return 0;
+    }
+
+    return 1;
+}
+
+static int json_callback_integer(void *opaque, long value)
+{
+    libxl__yajl_ctx *ctx = opaque;
+    libxl__json_object *obj;
+
+    DEBUG_GEN_VALUE(ctx, integer, value);
+
+    if ((obj = json_object_alloc(ctx->gc, JSON_INTEGER)) == NULL)
+        return 0;
+    obj->u.i = value;
+
+    if (json_object_append_to(ctx->gc, obj, ctx->current) == -1) {
+        libxl__json_object_free(ctx->gc, obj);
+        return 0;
+    }
+
+    return 1;
+}
+
+static int json_callback_double(void *opaque, double value)
+{
+    libxl__yajl_ctx *ctx = opaque;
+    libxl__json_object *obj;
+
+    DEBUG_GEN_VALUE(ctx, double, value);
+
+    if ((obj = json_object_alloc(ctx->gc, JSON_DOUBLE)) == NULL)
+        return 0;
+    obj->u.d = value;
+
+    if (json_object_append_to(ctx->gc, obj, ctx->current) == -1) {
+        libxl__json_object_free(ctx->gc, obj);
+        return 0;
+    }
+
+    return 1;
+}
+
+static int json_callback_string(void *opaque, const unsigned char *str,
+                                unsigned int len)
+{
+    libxl__yajl_ctx *ctx = opaque;
+    char *t = NULL;
+    libxl__json_object *obj = NULL;
+
+    t = malloc(len + 1);
+    if (t == NULL) {
+        LIBXL__LOG_ERRNO(libxl__gc_owner(ctx->gc), LIBXL__LOG_ERROR,
+                         "Failed to allocate");
+        return 0;
+    }
+
+    DEBUG_GEN_STRING(ctx, str, len);
+
+    strncpy(t, (const char *) str, len);
+    t[len] = 0;
+
+    if ((obj = json_object_alloc(ctx->gc, JSON_STRING)) == NULL) {
+        free(t);
+        return 0;
+    }
+    obj->u.string = t;
+
+    if (json_object_append_to(ctx->gc, obj, ctx->current) == -1) {
+        libxl__json_object_free(ctx->gc, obj);
+        return 0;
+    }
+
+    return 1;
+}
+
+static int json_callback_map_key(void *opaque, const unsigned char *str,
+                                 unsigned int len)
+{
+    libxl__yajl_ctx *ctx = opaque;
+    char *t = NULL;
+    libxl__json_object *obj = ctx->current;
+
+    t = malloc(len + 1);
+    if (t == NULL) {
+        LIBXL__LOG_ERRNO(libxl__gc_owner(ctx->gc), LIBXL__LOG_ERROR,
+                         "Failed to allocate");
+        return 0;
+    }
+
+    DEBUG_GEN_STRING(ctx, str, len);
+
+    strncpy(t, (const char *) str, len);
+    t[len] = 0;
+
+    if (libxl__json_object_is_map(obj)) {
+        libxl__json_map_node *node = malloc(sizeof (libxl__json_map_node));
+        if (node == NULL) {
+            LIBXL__LOG_ERRNO(libxl__gc_owner(ctx->gc), LIBXL__LOG_ERROR,
+                             "Failed to allocate");
+            return 0;
+        }
+
+        node->map_key = t;
+        node->obj = NULL;
+
+        if (flexarray_append(obj->u.map, node) == 2) {
+            LIBXL__LOG_ERRNO(libxl__gc_owner(ctx->gc), LIBXL__LOG_ERROR,
+                             "Failed to grow a flexarray");
+            return 0;
+        }
+    } else {
+        LIBXL__LOG(libxl__gc_owner(ctx->gc), LIBXL__LOG_ERROR,
+                   "Current json object is not a map");
+        return 0;
+    }
+
+    return 1;
+}
+
+static int json_callback_start_map(void *opaque)
+{
+    libxl__yajl_ctx *ctx = opaque;
+    libxl__json_object *obj = NULL;
+
+    DEBUG_GEN(ctx, map_open);
+
+    if ((obj = json_object_alloc(ctx->gc, JSON_MAP)) == NULL)
+        return 0;
+
+    if (ctx->current) {
+        if (json_object_append_to(ctx->gc, obj, ctx->current) == -1) {
+            libxl__json_object_free(ctx->gc, obj);
+            return 0;
+        }
+    }
+
+    ctx->current = obj;
+    if (ctx->head == NULL) {
+        ctx->head = obj;
+    }
+
+    return 1;
+}
+
+static int json_callback_end_map(void *opaque)
+{
+    libxl__yajl_ctx *ctx = opaque;
+
+    DEBUG_GEN(ctx, map_close);
+
+    if (ctx->current) {
+        ctx->current = ctx->current->parent;
+    } else {
+        LIBXL__LOG(libxl__gc_owner(ctx->gc), LIBXL__LOG_ERROR,
+                   "No current libxl__json_object, cannot use his parent.");
+        return 0;
+    }
+
+    return 1;
+}
+
+static int json_callback_start_array(void *opaque)
+{
+    libxl__yajl_ctx *ctx = opaque;
+    libxl__json_object *obj = NULL;
+
+    DEBUG_GEN(ctx, array_open);
+
+    if ((obj = json_object_alloc(ctx->gc, JSON_ARRAY)) == NULL)
+        return 0;
+
+    if (ctx->current) {
+        if (json_object_append_to(ctx->gc, obj, ctx->current) == -1) {
+            libxl__json_object_free(ctx->gc, obj);
+            return 0;
+        }
+    }
+
+    ctx->current = obj;
+    if (ctx->head == NULL) {
+        ctx->head = obj;
+    }
+
+    return 1;
+}
+
+static int json_callback_end_array(void *opaque)
+{
+    libxl__yajl_ctx *ctx = opaque;
+
+    DEBUG_GEN(ctx, array_close);
+
+    if (ctx->current) {
+        ctx->current = ctx->current->parent;
+    } else {
+        LIBXL__LOG(libxl__gc_owner(ctx->gc), LIBXL__LOG_ERROR,
+                   "No current libxl__json_object, cannot use his parent.");
+        return 0;
+    }
+
+    return 1;
+}
+
+static yajl_callbacks callbacks = {
+    json_callback_null,
+    json_callback_boolean,
+    json_callback_integer,
+    json_callback_double,
+    NULL,
+    json_callback_string,
+    json_callback_start_map,
+    json_callback_map_key,
+    json_callback_end_map,
+    json_callback_start_array,
+    json_callback_end_array
+};
+
+static void yajl_ctx_free(libxl__yajl_ctx *yajl_ctx)
+{
+    if (yajl_ctx->hand) {
+        yajl_free(yajl_ctx->hand);
+        yajl_ctx->hand = NULL;
+    }
+    DEBUG_GEN_FREE(yajl_ctx);
+}
+
+libxl__json_object *libxl__json_parse(libxl__gc *gc, const char *s)
+{
+    yajl_status status;
+    libxl__yajl_ctx yajl_ctx;
+
+    memset(&yajl_ctx, 0, sizeof (yajl_ctx));
+    yajl_ctx.gc = gc;
+
+    DEBUG_GEN_ALLOC(&yajl_ctx);
+
+    if (yajl_ctx.hand == NULL) {
+        yajl_parser_config cfg = {
+            .allowComments = 1,
+            .checkUTF8 = 1,
+        };
+        yajl_ctx.hand = yajl_alloc(&callbacks, &cfg, NULL, &yajl_ctx);
+    }
+    status = yajl_parse(yajl_ctx.hand, (const unsigned char *)s, strlen(s));
+    status = yajl_parse_complete(yajl_ctx.hand);
+
+    if (status == yajl_status_ok) {
+        libxl__json_object *o = yajl_ctx.head;
+
+        DEBUG_GEN_REPORT(&yajl_ctx);
+
+        yajl_ctx.head = NULL;
+
+        yajl_ctx_free(&yajl_ctx);
+        return o;
+    } else {
+        unsigned char *str = yajl_get_error(yajl_ctx.hand, 1,
+                                            (const unsigned char *)s,
+                                            strlen(s));
+
+        LIBXL__LOG(libxl__gc_owner(gc), LIBXL__LOG_ERROR,
+                   "yajl error: %s", str);
+        yajl_free_error(yajl_ctx.hand, str);
+
+        libxl__json_object_free(gc, yajl_ctx.head);
+        yajl_ctx_free(&yajl_ctx);
+        return NULL;
+    }
+}
-- 
Anthony PERARD


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel