Yajl has not seen much activity upstream recently. Switch to using Jansson >= 2.7. All the platforms we target on https://libvirt.org/platforms.html have a version >= 2.7 listed on the sites below: https://repology.org/metapackage/jansson/versions https://build.opensuse.org/package/show/devel:libraries:c_c++/libjansson Implement virJSONValue{From,To}String using Jansson, delete the yajl code (and the related virJSONParser structure) and report an error if someone explicitly specifies --with-yajl. Also adjust the test data to account for Jansson's different whitespace usage for empty arrays and tune up the specfile to keep 'make rpm' working when bisecting. Signed-off-by: Ján Tomko <jtomko@xxxxxxxxxx> --- src/util/virjson.c | 211 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 211 insertions(+) diff --git a/src/util/virjson.c b/src/util/virjson.c index 0559d40b64..2f7d624bb3 100644 --- a/src/util/virjson.c +++ b/src/util/virjson.c @@ -2008,6 +2008,217 @@ virJSONValueToString(virJSONValuePtr object, } +#elif WITH_JANSSON +# include <jansson.h> + +static virJSONValuePtr +virJSONValueFromJansson(json_t *json) +{ + virJSONValuePtr ret = NULL; + const char *key; + json_t *cur; + size_t i; + + switch (json_typeof(json)) { + case JSON_OBJECT: + ret = virJSONValueNewObject(); + if (!ret) + goto error; + + json_object_foreach(json, key, cur) { + virJSONValuePtr val = virJSONValueFromJansson(cur); + if (!val) + goto error; + + if (virJSONValueObjectAppend(ret, key, val) < 0) { + virJSONValueFree(val); + goto error; + } + } + + break; + + case JSON_ARRAY: + ret = virJSONValueNewArray(); + if (!ret) + goto error; + + json_array_foreach(json, i, cur) { + virJSONValuePtr val = virJSONValueFromJansson(cur); + if (!val) + goto error; + + if (virJSONValueArrayAppend(ret, val) < 0) { + virJSONValueFree(val); + goto error; + } + } + break; + + case JSON_STRING: + ret = virJSONValueNewStringLen(json_string_value(json), + json_string_length(json)); + break; + + case JSON_INTEGER: + ret = virJSONValueNewNumberLong(json_integer_value(json)); + break; + + case JSON_REAL: + ret = virJSONValueNewNumberDouble(json_real_value(json)); + break; + + case JSON_TRUE: + case JSON_FALSE: + ret = virJSONValueNewBoolean(json_boolean_value(json)); + break; + + case JSON_NULL: + ret = virJSONValueNewNull(); + break; + } + + return ret; + + error: + virJSONValueFree(ret); + return NULL; +} + +virJSONValuePtr +virJSONValueFromString(const char *jsonstring) +{ + virJSONValuePtr ret = NULL; + json_t *json; + json_error_t error; + size_t flags = JSON_REJECT_DUPLICATES | + JSON_DECODE_ANY; + + if (!(json = json_loads(jsonstring, flags, &error))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("failed to parse JSON %d:%d: %s"), + error.line, error.column, error.text); + return NULL; + } + + ret = virJSONValueFromJansson(json); + json_decref(json); + return ret; +} + + +static json_t * +virJSONValueToJansson(virJSONValuePtr object) +{ + json_t *ret = NULL; + size_t i; + + switch ((virJSONType)object->type) { + case VIR_JSON_TYPE_OBJECT: + ret = json_object(); + if (!ret) { + virReportOOMError(); + goto error; + } + for (i = 0; i < object->data.object.npairs; i++) { + virJSONObjectPairPtr cur = object->data.object.pairs + i; + json_t *val = virJSONValueToJansson(cur->value); + + if (!val) + goto error; + if (json_object_set_new(ret, cur->key, val) < 0) { + virReportOOMError(); + goto error; + } + } + break; + + case VIR_JSON_TYPE_ARRAY: + ret = json_array(); + if (!ret) { + virReportOOMError(); + goto error; + } + for (i = 0; i < object->data.array.nvalues; i++) { + virJSONValuePtr cur = object->data.array.values[i]; + json_t *val = virJSONValueToJansson(cur); + + if (!val) + goto error; + if (json_array_append_new(ret, val) < 0) { + virReportOOMError(); + goto error; + } + } + break; + + case VIR_JSON_TYPE_STRING: + ret = json_string(object->data.string); + break; + + case VIR_JSON_TYPE_NUMBER: { + long long ll_val; + double d_val; + if (virStrToLong_ll(object->data.number, NULL, 10, &ll_val) < 0) { + if (virStrToDouble(object->data.number, NULL, &d_val) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("JSON value is not a number")); + return NULL; + } + ret = json_real(d_val); + } else { + ret = json_integer(ll_val); + } + } + break; + + case VIR_JSON_TYPE_BOOLEAN: + ret = json_boolean(object->data.boolean); + break; + + case VIR_JSON_TYPE_NULL: + ret = json_null(); + break; + + default: + virReportEnumRangeError(virJSONType, object->type); + goto error; + } + if (!ret) + virReportOOMError(); + return ret; + + error: + json_decref(ret); + return NULL; +} + + +char * +virJSONValueToString(virJSONValuePtr object, + bool pretty) +{ + size_t flags = JSON_ENCODE_ANY; + json_t *json; + char *str = NULL; + + if (pretty) + flags |= JSON_INDENT(2); + else + flags |= JSON_COMPACT; + + json = virJSONValueToJansson(object); + if (!json) + return NULL; + + str = json_dumps(json, flags); + if (!str) + virReportOOMError(); + json_decref(json); + return str; +} + + #else virJSONValuePtr virJSONValueFromString(const char *jsonstring ATTRIBUTE_UNUSED) -- 2.16.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list