diff --git a/configure.ac b/configure.ac index b4a9b30691..2dba99838f 100644 --- a/configure.ac +++ b/configure.ac @@ -2982,6 +2982,10 @@ AC_DEFUN if test "${HAVE_JSON}" = yes; then AC_DEFINE(HAVE_JSON, 1, [Define if using Jansson.]) JSON_OBJ=json.o + OLDLIBS="$LIBS" + LIBS="$LIBS $JSON_LIBS" + AC_CHECK_FUNCS(json_dumpb) + LIBS="$OLDLIBS" fi # Windows loads libjansson dynamically diff --git a/src/json.c b/src/json.c index 928825e034..361581c2f4 100644 --- a/src/json.c +++ b/src/json.c @@ -31,7 +31,7 @@ along with GNU Emacs. If not, see . */ #include "coding.h" #define JSON_HAS_ERROR_CODE (JANSSON_VERSION_HEX >= 0x020B00) - +#undef HAVE_JSON_DUMPB #ifdef WINDOWSNT # include # include "w32common.h" @@ -53,6 +53,11 @@ DEF_DLL_FN (json_t *, json_integer, (json_int_t value)); DEF_DLL_FN (json_t *, json_real, (double value)); DEF_DLL_FN (json_t *, json_stringn, (const char *value, size_t len)); DEF_DLL_FN (char *, json_dumps, (const json_t *json, size_t flags)); +# ifdef HAVE_JSON_DUMPB +DEF_DLL_FN (void, json_dumpb, (const json_t *json, char *buffer, + size_t size, + size_t flags)); +# endif DEF_DLL_FN (int, json_dump_callback, (const json_t *json, json_dump_callback_t callback, void *data, size_t flags)); @@ -104,6 +109,9 @@ init_json_functions (void) LOAD_DLL_FN (library, json_real); LOAD_DLL_FN (library, json_stringn); LOAD_DLL_FN (library, json_dumps); +# ifdef HAVE_JSON_DUMPB + LOAD_DLL_FN (library, json_dumpb); +# endif LOAD_DLL_FN (library, json_dump_callback); LOAD_DLL_FN (library, json_integer_value); LOAD_DLL_FN (library, json_real_value); @@ -605,6 +613,10 @@ usage: (json-serialize OBJECT &rest ARGS) */) { ptrdiff_t count = SPECPDL_INDEX (); +#ifdef HAVE_JSON_DUMPB + USE_SAFE_ALLOCA; +#endif + #ifdef WINDOWSNT if (!json_initialized) { @@ -625,16 +637,34 @@ usage: (json-serialize OBJECT &rest ARGS) */) json_parse_args (nargs - 1, args + 1, &conf, false); json_t *json = lisp_to_json_toplevel (args[0], &conf); - record_unwind_protect_ptr (json_release_object, json); +#ifdef HAVE_JSON_DUMPB + /* Called with NULL to determine the size of buffer needed. */ + size_t size = json_dumpb (json, NULL, 0, 0); + char *string = SAFE_ALLOCA (size); + + size = json_dumpb (json, string, size, JSON_COMPACT); + + json_release_object (json); + + if (!size) + json_out_of_memory (); + + + return SAFE_FREE_UNBIND_TO (count, json_make_string (string, size)); +#else /* If desired, we might want to add the following flags: JSON_DECODE_ANY, JSON_ALLOW_NUL. */ char *string = json_dumps (json, JSON_COMPACT); + + json_release_object (json); + if (string == NULL) json_out_of_memory (); record_unwind_protect_ptr (json_free, string); return unbind_to (count, json_build_string (string)); +#endif } struct json_buffer_and_size