Yajl has not seen much activity upstream recently.
Switch to using Jansson >= 2.5.
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
Additionally, Ubuntu 14.04 on Travis-CI has 2.5. Set the requirement
to 2.5 since we don't use anything from newer versions.
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@redhat.com>
BuildRequires: libudev-devel >= 145
%endif
BuildRequires: libpciaccess-devel >= 0.10.9
-BuildRequires: yajl-devel
+BuildRequires: jansson-devel
%if %{with_sanlock}
BuildRequires: sanlock-devel >= 2.4
%endif
--without-apparmor \
--without-hal \
--with-udev \
- --with-yajl \
+ --with-jansson \
%{?arg_sanlock} \
--with-libpcap \
--with-macvtap \
bsd_nss=no
fail=0
if test "x$with_nss_plugin" != "xno" ; then
- if test "x$with_yajl" != "xyes" ; then
+ if test "x$with_jansson" != "xyes" ; then
if test "x$with_nss_plugin" = "xyes" ; then
- AC_MSG_ERROR([Can't build nss plugin without yajl])
+ AC_MSG_ERROR([Can't build nss plugin without JSON support])
else
with_nss_plugin=no
fi
AC_DEFUN([LIBVIRT_CHECK_YAJL],[
dnl YAJL JSON library http://lloyd.github.com/yajl/
- if test "$with_qemu:$with_yajl" = yes:check; then
- dnl Some versions of qemu require the use of yajl; try to detect them
- dnl here, although we do not require qemu to exist in order to compile.
- dnl This check mirrors src/qemu/qemu_capabilities.c
- AC_PATH_PROGS([QEMU], [qemu-kvm qemu kvm qemu-system-x86_64],
- [], [$PATH:/usr/bin:/usr/libexec])
- if test -x "$QEMU"; then
- if $QEMU -help 2>/dev/null | grep -q libvirt; then
- with_yajl=yes
- else
- [qemu_version_sed='s/.*ersion \([0-9.,]*\).*/\1/']
- qemu_version=`$QEMU -version | sed "$qemu_version_sed"`
- case $qemu_version in
- [[1-9]].* | 0.15.* ) with_yajl=yes ;;
- 0.* | '' ) ;;
- *) AC_MSG_ERROR([Unexpected qemu version string]) ;;
- esac
- fi
- fi
+ if test "$with_yajl" = yes; then
+ AC_MSG_ERROR([Compilation with YAJL is no longer supported])
fi
-
- LIBVIRT_CHECK_LIB_ALT([YAJL], [yajl],
- [yajl_parse_complete], [yajl/yajl_common.h],
- [YAJL2], [yajl],
- [yajl_tree_parse], [yajl/yajl_common.h])
+ with_yajl=no
])
AC_DEFUN([LIBVIRT_RESULT_YAJL],[
libvirt_admin_la_CFLAGS += \
$(XDR_CFLAGS) \
$(CAPNG_CFLAGS) \
- $(YAJL_CFLAGS) \
+ $(JANSSON_CFLAGS) \
$(SSH2_CFLAGS) \
$(SASL_CFLAGS) \
$(GNUTLS_CFLAGS) \
libvirt_admin_la_LIBADD += \
$(CAPNG_LIBS) \
- $(YAJL_LIBS) \
+ $(JANSSON_LIBS) \
$(DEVMAPPER_LIBS) \
$(LIBXML_LIBS) \
$(SSH2_LIBS) \
libvirt_nss_la_CFLAGS = \
-DLIBVIRT_NSS \
$(AM_CFLAGS) \
- $(YAJL_CFLAGS) \
+ $(JANSSON_CFLAGS) \
$(NULL)
libvirt_nss_la_LDFLAGS = \
$(AM_LDFLAGS) \
$(NULL)
libvirt_nss_la_LIBADD = \
- $(YAJL_LIBS) \
+ $(JANSSON_LIBS) \
$(NULL)
endif WITH_NSS
*/
if ((!useAgent) ||
(ret < 0 && (acpiRequested || !flags))) {
-#if !WITH_YAJL
+#if !WITH_JANSSON
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("ACPI reboot is not supported without the JSON monitor"));
goto endjob;
$(NULL)
libvirt_util_la_CFLAGS = \
$(CAPNG_CFLAGS) \
- $(YAJL_CFLAGS) \
+ $(JANSSON_CFLAGS) \
$(LIBNL_CFLAGS) \
$(AM_CFLAGS) \
$(AUDIT_CFLAGS) \
$(NULL)
libvirt_util_la_LIBADD = \
$(CAPNG_LIBS) \
- $(YAJL_LIBS) \
+ $(JANSSON_LIBS) \
$(LIBNL_LIBS) \
$(THREAD_LIBS) \
$(AUDIT_LIBS) \
}
+#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 = virJSONValueNewString(json_string_value(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:
+ ret = virJSONValueNewBoolean(true);
+ break;
+
+ case JSON_FALSE:
+ ret = virJSONValueNewBoolean(false);
+ 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)
+ goto no_memory;
+ 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) {
+ json_decref(val);
+ goto no_memory;
+ }
+ }
+ break;
+
+ case VIR_JSON_TYPE_ARRAY:
+ ret = json_array();
+ if (!ret)
+ goto no_memory;
+ 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) {
+ json_decref(val);
+ goto no_memory;
+ }
+ }
+ 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)
+ goto no_memory;
+ return ret;
+
+ no_memory:
+ virReportOOMError();
+ 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)
$(SASL_CFLAGS) \
$(SELINUX_CFLAGS) \
$(APPARMOR_CFLAGS) \
- $(YAJL_CFLAGS) \
+ $(JANSSON_CFLAGS) \
$(COVERAGE_CFLAGS) \
$(XDR_CFLAGS) \
$(WARN_CFLAGS)
test_programs += objectlocking
endif WITH_CIL
-if WITH_YAJL
+if WITH_JANSSON
test_programs += virjsontest
-endif WITH_YAJL
+endif WITH_JANSSON
test_programs += \
networkxml2xmltest \
test_libraries += virdeterministichashmock.la
-if WITH_YAJL
+if WITH_JANSSON
virmacmaptest_SOURCES = \
virmacmaptest.c testutils.h testutils.c
virmacmaptest_LDADD = $(LDADDS)
test_programs += virmacmaptest
-else ! WITH_YAJL
+else ! WITH_JANSSON
EXTRA_DIST += virmacmaptest.c
-endif ! WITH_YAJL
+endif ! WITH_JANSSON
virnetdevtest_SOURCES = \
virnetdevtest.c testutils.h testutils.c
#include "cpu/cpu_map.h"
#include "virstring.h"
-#if WITH_QEMU && WITH_YAJL
+#if WITH_QEMU && WITH_JANSSON
# include "testutilsqemu.h"
# include "qemumonitortestutils.h"
# define __QEMU_CAPSPRIV_H_ALLOW__
int result;
};
-#if WITH_QEMU && WITH_YAJL
+#if WITH_QEMU && WITH_JANSSON
static virQEMUDriver driver;
#endif
JSON_MODELS_REQUIRED,
} cpuTestCPUIDJson;
-#if WITH_QEMU && WITH_YAJL
+#if WITH_QEMU && WITH_JANSSON
static virQEMUCapsPtr
cpuTestMakeQEMUCaps(const struct data *data)
{
return 0;
}
-#else /* if WITH_QEMU && WITH_YAJL */
+#else /* if WITH_QEMU && WITH_JANSSON */
static int
cpuTestGetCPUModels(const struct data *data,
}
-#if WITH_QEMU && WITH_YAJL
+#if WITH_QEMU && WITH_JANSSON
static int
cpuTestJSONCPUID(const void *arg)
{
virDomainCapsCPUModelsPtr ppc_models = NULL;
int ret = 0;
-#if WITH_QEMU && WITH_YAJL
+#if WITH_QEMU && WITH_JANSSON
if (qemuTestDriverInit(&driver) < 0)
return EXIT_FAILURE;
host "/" cpu " (" #models ")", \
host, cpu, models, 0, result)
-#if WITH_QEMU && WITH_YAJL
+#if WITH_QEMU && WITH_JANSSON
# define DO_TEST_JSON(arch, host, json) \
do { \
if (json == JSON_MODELS) { \
DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-X5460", JSON_NONE);
cleanup:
-#if WITH_QEMU && WITH_YAJL
+#if WITH_QEMU && WITH_JANSSON
qemuTestDriverFree(&driver);
#endif
#include "testutils.h"
-#if defined(WITH_LIBXL) && defined(WITH_YAJL) && defined(HAVE_LIBXL_DOMAIN_CONFIG_FROM_JSON)
+#if defined(WITH_LIBXL) && defined(WITH_JANSSON) && defined(HAVE_LIBXL_DOMAIN_CONFIG_FROM_JSON)
# include "internal.h"
# include "viralloc.h"
return EXIT_AM_SKIP;
}
-#endif /* WITH_LIBXL && WITH_YAJL && HAVE_LIBXL_DOMAIN_CONFIG_FROM_JSON */
+#endif /* WITH_LIBXL && WITH_JANSSON && HAVE_LIBXL_DOMAIN_CONFIG_FROM_JSON */
{
int ret = 0;
-#if !WITH_YAJL
+#if !WITH_JANSSON
fputs("libvirt not compiled with JSON support, skipping this test\n", stderr);
return EXIT_AM_SKIP;
#endif
goto cleanup;
virBufferAdd(&buf, jsonstr, -1);
+ virBufferAddLit(&buf, "\n");
VIR_FREE(jsonstr);
}
int ret = 0;
testQemuData data;
-#if !WITH_YAJL
+#if !WITH_JANSSON
fputs("libvirt not compiled with JSON support, skipping this test\n", stderr);
return EXIT_AM_SKIP;
#endif
testQemuData data;
-#if !WITH_YAJL
+#if !WITH_JANSSON
fputs("libvirt not compiled with JSON support, skipping this test\n", stderr);
return EXIT_AM_SKIP;
#endif
int ret = 0;
testQemuCommandBuildObjectFromJSONData data1;
-#if !WITH_YAJL
+#if !WITH_JANSSON
fputs("libvirt not compiled with JSON support, skipping this test\n", stderr);
return EXIT_AM_SKIP;
#endif
struct qemuHotplugTestData data = {0};
struct testQemuHotplugCpuParams cpudata;
-#if !WITH_YAJL
+#if !WITH_JANSSON
fputs("libvirt not compiled with JSON support, skipping this test\n", stderr);
return EXIT_AM_SKIP;
#endif
virQEMUDriver driver;
int ret = 0;
-#if !WITH_YAJL
+#if !WITH_JANSSON
fputs("libvirt not compiled with JSON support, skipping this test\n", stderr);
return EXIT_AM_SKIP;
#endif
virJSONValuePtr metaschema = NULL;
char *metaschemastr = NULL;
-#if !WITH_YAJL
+#if !WITH_JANSSON
fputs("libvirt not compiled with JSON support, skipping this test\n", stderr);
return EXIT_AM_SKIP;
#endif
#include <config.h>
-#if defined(WITH_LIBXL) && defined(WITH_YAJL)
+#if defined(WITH_LIBXL) && defined(WITH_JANSSON)
# include "virmock.h"
# include <sys/stat.h>
# include <unistd.h>
return real_stat(path, sb);
}
-#endif /* WITH_LIBXL && WITH_YAJL */
+#endif /* WITH_LIBXL && WITH_JANSSON */
#define VIR_FROM_THIS VIR_FROM_RPC
-#if defined(HAVE_SOCKETPAIR) && defined(WITH_YAJL)
+#if defined(HAVE_SOCKETPAIR) && defined(WITH_JANSSON)
struct testClientPriv {
int magic;
};
" <host name='example.org' port='6000'/>\n"
"</source>\n");
-#ifdef WITH_YAJL
+#ifdef WITH_JANSSON
TEST_BACKING_PARSE("json:", NULL);
TEST_BACKING_PARSE("json:asdgsdfg", NULL);
TEST_BACKING_PARSE("json:{}", NULL);
"<source protocol='vxhs' name='c6718f6b-0401-441d-a8c3-1f0064d75ee0'>\n"
" <host name='example.com' port='9999'/>\n"
"</source>\n");
-#endif /* WITH_YAJL */
+#endif /* WITH_JANSSON */
cleanup:
/* Final cleanup */