Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
/* JSON parsing and serialization.
|
|
|
|
|
2018-12-31 18:41:28 -08:00
|
|
|
Copyright (C) 2017-2019 Free Software Foundation, Inc.
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
|
|
|
|
This file is part of GNU Emacs.
|
|
|
|
|
|
|
|
GNU Emacs is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or (at
|
2018-07-30 00:18:27 +02:00
|
|
|
your option) any later version.
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
|
|
|
|
GNU Emacs 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 General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
#include <errno.h>
|
|
|
|
#include <stddef.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#include <jansson.h>
|
|
|
|
|
|
|
|
#include "lisp.h"
|
|
|
|
#include "buffer.h"
|
|
|
|
#include "coding.h"
|
|
|
|
|
2017-12-20 18:36:35 +01:00
|
|
|
#define JSON_HAS_ERROR_CODE (JANSSON_VERSION_HEX >= 0x020B00)
|
|
|
|
|
2017-12-10 18:36:37 +02:00
|
|
|
#ifdef WINDOWSNT
|
|
|
|
# include <windows.h>
|
2018-08-20 17:00:27 -04:00
|
|
|
# include "w32common.h"
|
2017-12-10 18:36:37 +02:00
|
|
|
# include "w32.h"
|
|
|
|
|
|
|
|
DEF_DLL_FN (void, json_set_alloc_funcs,
|
|
|
|
(json_malloc_t malloc_fn, json_free_t free_fn));
|
|
|
|
DEF_DLL_FN (void, json_delete, (json_t *json));
|
|
|
|
DEF_DLL_FN (json_t *, json_array, (void));
|
|
|
|
DEF_DLL_FN (int, json_array_append_new, (json_t *array, json_t *value));
|
|
|
|
DEF_DLL_FN (size_t, json_array_size, (const json_t *array));
|
|
|
|
DEF_DLL_FN (json_t *, json_object, (void));
|
|
|
|
DEF_DLL_FN (int, json_object_set_new,
|
|
|
|
(json_t *object, const char *key, json_t *value));
|
|
|
|
DEF_DLL_FN (json_t *, json_null, (void));
|
|
|
|
DEF_DLL_FN (json_t *, json_true, (void));
|
|
|
|
DEF_DLL_FN (json_t *, json_false, (void));
|
|
|
|
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));
|
|
|
|
DEF_DLL_FN (int, json_dump_callback,
|
|
|
|
(const json_t *json, json_dump_callback_t callback, void *data,
|
|
|
|
size_t flags));
|
|
|
|
DEF_DLL_FN (json_int_t, json_integer_value, (const json_t *integer));
|
|
|
|
DEF_DLL_FN (double, json_real_value, (const json_t *real));
|
|
|
|
DEF_DLL_FN (const char *, json_string_value, (const json_t *string));
|
|
|
|
DEF_DLL_FN (size_t, json_string_length, (const json_t *string));
|
|
|
|
DEF_DLL_FN (json_t *, json_array_get, (const json_t *array, size_t index));
|
2017-12-25 19:21:58 +02:00
|
|
|
DEF_DLL_FN (json_t *, json_object_get, (const json_t *object, const char *key));
|
2017-12-10 18:36:37 +02:00
|
|
|
DEF_DLL_FN (size_t, json_object_size, (const json_t *object));
|
|
|
|
DEF_DLL_FN (const char *, json_object_iter_key, (void *iter));
|
|
|
|
DEF_DLL_FN (void *, json_object_iter, (json_t *object));
|
|
|
|
DEF_DLL_FN (json_t *, json_object_iter_value, (void *iter));
|
|
|
|
DEF_DLL_FN (void *, json_object_key_to_iter, (const char *key));
|
|
|
|
DEF_DLL_FN (void *, json_object_iter_next, (json_t *object, void *iter));
|
|
|
|
DEF_DLL_FN (json_t *, json_loads,
|
|
|
|
(const char *input, size_t flags, json_error_t *error));
|
|
|
|
DEF_DLL_FN (json_t *, json_load_callback,
|
|
|
|
(json_load_callback_t callback, void *data, size_t flags,
|
|
|
|
json_error_t *error));
|
|
|
|
|
|
|
|
/* This is called by json_decref, which is an inline function. */
|
|
|
|
void json_delete(json_t *json)
|
|
|
|
{
|
|
|
|
fn_json_delete (json);
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool json_initialized;
|
|
|
|
|
|
|
|
static bool
|
|
|
|
init_json_functions (void)
|
|
|
|
{
|
|
|
|
HMODULE library = w32_delayed_load (Qjson);
|
|
|
|
|
|
|
|
if (!library)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
LOAD_DLL_FN (library, json_set_alloc_funcs);
|
|
|
|
LOAD_DLL_FN (library, json_delete);
|
|
|
|
LOAD_DLL_FN (library, json_array);
|
|
|
|
LOAD_DLL_FN (library, json_array_append_new);
|
|
|
|
LOAD_DLL_FN (library, json_array_size);
|
|
|
|
LOAD_DLL_FN (library, json_object);
|
|
|
|
LOAD_DLL_FN (library, json_object_set_new);
|
|
|
|
LOAD_DLL_FN (library, json_null);
|
|
|
|
LOAD_DLL_FN (library, json_true);
|
|
|
|
LOAD_DLL_FN (library, json_false);
|
|
|
|
LOAD_DLL_FN (library, json_integer);
|
|
|
|
LOAD_DLL_FN (library, json_real);
|
|
|
|
LOAD_DLL_FN (library, json_stringn);
|
|
|
|
LOAD_DLL_FN (library, json_dumps);
|
|
|
|
LOAD_DLL_FN (library, json_dump_callback);
|
|
|
|
LOAD_DLL_FN (library, json_integer_value);
|
|
|
|
LOAD_DLL_FN (library, json_real_value);
|
|
|
|
LOAD_DLL_FN (library, json_string_value);
|
|
|
|
LOAD_DLL_FN (library, json_string_length);
|
|
|
|
LOAD_DLL_FN (library, json_array_get);
|
2017-12-25 19:21:58 +02:00
|
|
|
LOAD_DLL_FN (library, json_object_get);
|
2017-12-10 18:36:37 +02:00
|
|
|
LOAD_DLL_FN (library, json_object_size);
|
|
|
|
LOAD_DLL_FN (library, json_object_iter_key);
|
|
|
|
LOAD_DLL_FN (library, json_object_iter);
|
|
|
|
LOAD_DLL_FN (library, json_object_iter_value);
|
|
|
|
LOAD_DLL_FN (library, json_object_key_to_iter);
|
|
|
|
LOAD_DLL_FN (library, json_object_iter_next);
|
|
|
|
LOAD_DLL_FN (library, json_loads);
|
|
|
|
LOAD_DLL_FN (library, json_load_callback);
|
|
|
|
|
|
|
|
init_json ();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define json_set_alloc_funcs fn_json_set_alloc_funcs
|
|
|
|
#define json_array fn_json_array
|
|
|
|
#define json_array_append_new fn_json_array_append_new
|
|
|
|
#define json_array_size fn_json_array_size
|
|
|
|
#define json_object fn_json_object
|
|
|
|
#define json_object_set_new fn_json_object_set_new
|
|
|
|
#define json_null fn_json_null
|
|
|
|
#define json_true fn_json_true
|
|
|
|
#define json_false fn_json_false
|
|
|
|
#define json_integer fn_json_integer
|
|
|
|
#define json_real fn_json_real
|
|
|
|
#define json_stringn fn_json_stringn
|
|
|
|
#define json_dumps fn_json_dumps
|
|
|
|
#define json_dump_callback fn_json_dump_callback
|
|
|
|
#define json_integer_value fn_json_integer_value
|
|
|
|
#define json_real_value fn_json_real_value
|
|
|
|
#define json_string_value fn_json_string_value
|
|
|
|
#define json_string_length fn_json_string_length
|
|
|
|
#define json_array_get fn_json_array_get
|
2017-12-25 19:21:58 +02:00
|
|
|
#define json_object_get fn_json_object_get
|
2017-12-10 18:36:37 +02:00
|
|
|
#define json_object_size fn_json_object_size
|
|
|
|
#define json_object_iter_key fn_json_object_iter_key
|
|
|
|
#define json_object_iter fn_json_object_iter
|
|
|
|
#define json_object_iter_value fn_json_object_iter_value
|
|
|
|
#define json_object_key_to_iter fn_json_object_key_to_iter
|
|
|
|
#define json_object_iter_next fn_json_object_iter_next
|
|
|
|
#define json_loads fn_json_loads
|
|
|
|
#define json_load_callback fn_json_load_callback
|
|
|
|
|
|
|
|
#endif /* WINDOWSNT */
|
|
|
|
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
/* We install a custom allocator so that we can avoid objects larger
|
2017-12-14 19:53:58 +02:00
|
|
|
than PTRDIFF_MAX. Such objects wouldn't play well with the rest of
|
|
|
|
Emacs's codebase, which generally uses ptrdiff_t for sizes and
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
indices. The other functions in this file also generally assume
|
2018-08-07 17:28:35 +03:00
|
|
|
that size_t values never exceed PTRDIFF_MAX.
|
|
|
|
|
|
|
|
In addition, we need to use a custom allocator because on
|
|
|
|
MS-Windows we replace malloc/free with our own functions, see
|
|
|
|
w32heap.c, so we must force the library to use our allocator, or
|
|
|
|
else we won't be able to free storage allocated by the library. */
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
|
|
|
|
static void *
|
|
|
|
json_malloc (size_t size)
|
|
|
|
{
|
|
|
|
if (size > PTRDIFF_MAX)
|
|
|
|
{
|
|
|
|
errno = ENOMEM;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return malloc (size);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
json_free (void *ptr)
|
|
|
|
{
|
|
|
|
free (ptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
init_json (void)
|
|
|
|
{
|
|
|
|
json_set_alloc_funcs (json_malloc, json_free);
|
|
|
|
}
|
|
|
|
|
2017-12-20 18:36:35 +01:00
|
|
|
#if !JSON_HAS_ERROR_CODE
|
|
|
|
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
/* Return whether STRING starts with PREFIX. */
|
|
|
|
|
|
|
|
static bool
|
|
|
|
json_has_prefix (const char *string, const char *prefix)
|
|
|
|
{
|
|
|
|
size_t string_len = strlen (string);
|
|
|
|
size_t prefix_len = strlen (prefix);
|
|
|
|
return string_len >= prefix_len && memcmp (string, prefix, prefix_len) == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return whether STRING ends with SUFFIX. */
|
|
|
|
|
|
|
|
static bool
|
|
|
|
json_has_suffix (const char *string, const char *suffix)
|
|
|
|
{
|
|
|
|
size_t string_len = strlen (string);
|
|
|
|
size_t suffix_len = strlen (suffix);
|
|
|
|
return string_len >= suffix_len
|
|
|
|
&& memcmp (string + string_len - suffix_len, suffix, suffix_len) == 0;
|
|
|
|
}
|
|
|
|
|
2017-12-20 18:36:35 +01:00
|
|
|
#endif
|
|
|
|
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
/* Create a multibyte Lisp string from the UTF-8 string in
|
|
|
|
[DATA, DATA + SIZE). If the range [DATA, DATA + SIZE) does not
|
2017-12-22 02:02:24 +01:00
|
|
|
contain a valid UTF-8 string, an unspecified string is returned.
|
|
|
|
Note that all callers below either pass only value UTF-8 strings or
|
|
|
|
use this function for formatting error messages; in the latter case
|
|
|
|
correctness isn't critical. */
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
|
|
|
|
static Lisp_Object
|
|
|
|
json_make_string (const char *data, ptrdiff_t size)
|
|
|
|
{
|
|
|
|
return code_convert_string (make_specified_string (data, -1, size, false),
|
|
|
|
Qutf_8_unix, Qt, false, true, true);
|
|
|
|
}
|
|
|
|
|
2019-03-21 23:55:28 -04:00
|
|
|
/* Create a multibyte Lisp string from the NUL-terminated UTF-8
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
string beginning at DATA. If the string is not a valid UTF-8
|
2017-12-22 02:02:24 +01:00
|
|
|
string, an unspecified string is returned. Note that all callers
|
|
|
|
below either pass only value UTF-8 strings or use this function for
|
|
|
|
formatting error messages; in the latter case correctness isn't
|
|
|
|
critical. */
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
|
|
|
|
static Lisp_Object
|
|
|
|
json_build_string (const char *data)
|
|
|
|
{
|
|
|
|
return json_make_string (data, strlen (data));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return a unibyte string containing the sequence of UTF-8 encoding
|
|
|
|
units of the UTF-8 representation of STRING. If STRING does not
|
|
|
|
represent a sequence of Unicode scalar values, return a string with
|
|
|
|
unspecified contents. */
|
|
|
|
|
|
|
|
static Lisp_Object
|
|
|
|
json_encode (Lisp_Object string)
|
|
|
|
{
|
2017-12-18 23:58:48 +01:00
|
|
|
/* FIXME: Raise an error if STRING is not a scalar value
|
|
|
|
sequence. */
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
return code_convert_string (string, Qutf_8_unix, Qt, true, true, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
static _Noreturn void
|
|
|
|
json_out_of_memory (void)
|
|
|
|
{
|
|
|
|
xsignal0 (Qjson_out_of_memory);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Signal a Lisp error corresponding to the JSON ERROR. */
|
|
|
|
|
|
|
|
static _Noreturn void
|
|
|
|
json_parse_error (const json_error_t *error)
|
|
|
|
{
|
|
|
|
Lisp_Object symbol;
|
2017-12-20 18:36:35 +01:00
|
|
|
#if JSON_HAS_ERROR_CODE
|
2017-12-19 00:00:31 +01:00
|
|
|
switch (json_error_code (error))
|
|
|
|
{
|
|
|
|
case json_error_premature_end_of_input:
|
|
|
|
symbol = Qjson_end_of_file;
|
2017-12-20 18:30:23 +01:00
|
|
|
break;
|
2017-12-19 00:00:31 +01:00
|
|
|
case json_error_end_of_input_expected:
|
|
|
|
symbol = Qjson_trailing_content;
|
2017-12-20 18:30:23 +01:00
|
|
|
break;
|
2017-12-19 00:00:31 +01:00
|
|
|
default:
|
|
|
|
symbol = Qjson_parse_error;
|
2017-12-20 18:30:23 +01:00
|
|
|
break;
|
2017-12-19 00:00:31 +01:00
|
|
|
}
|
|
|
|
#else
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
if (json_has_suffix (error->text, "expected near end of file"))
|
|
|
|
symbol = Qjson_end_of_file;
|
|
|
|
else if (json_has_prefix (error->text, "end of file expected"))
|
|
|
|
symbol = Qjson_trailing_content;
|
|
|
|
else
|
|
|
|
symbol = Qjson_parse_error;
|
2017-12-19 00:00:31 +01:00
|
|
|
#endif
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
xsignal (symbol,
|
|
|
|
list5 (json_build_string (error->text),
|
Rename integerp->fixnum, etc, in preparation for bignums
* src/json.c, src/keyboard.c, src/keyboard.h, src/keymap.c,
src/kqueue.c, src/lcms.c, src/lisp.h, src/lread.c, src/macros.c,
src/marker.c, src/menu.c, src/minibuf.c, src/msdos.c, src/print.c,
src/process.c, src/profiler.c, src/search.c, src/sound.c,
src/syntax.c, src/sysdep.c, src/term.c, src/terminal.c,
src/textprop.c, src/undo.c, src/w16select.c, src/w32.c,
src/w32console.c, src/w32cygwinx.c, src/w32fns.c, src/w32font.c,
src/w32inevt.c, src/w32proc.c, src/w32select.c, src/w32term.c,
src/w32uniscribe.c, src/widget.c, src/window.c, src/xdisp.c,
src/xfaces.c, src/xfns.c, src/xfont.c, src/xftfont.c, src/xmenu.c,
src/xrdb.c, src/xselect.c, src/xterm.c, src/xwidget.c: Rename
INTEGERP->FIXNUM, make_number->make_fixnum, CHECK_NUMBER->CHECK_FIXNUM,
make_natnum->make_fixed_natum, NUMBERP->FIXED_OR_FLOATP,
NATNUMP->FIXNATP, CHECK_NATNUM->CHECK_FIXNAT.
2018-07-06 21:56:17 -06:00
|
|
|
json_build_string (error->source), make_fixed_natnum (error->line),
|
|
|
|
make_fixed_natnum (error->column), make_fixed_natnum (error->position)));
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
json_release_object (void *object)
|
|
|
|
{
|
|
|
|
json_decref (object);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Signal an error if OBJECT is not a string, or if OBJECT contains
|
2019-03-21 23:55:28 -04:00
|
|
|
embedded NUL characters. */
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
|
|
|
|
static void
|
2019-03-21 23:55:28 -04:00
|
|
|
check_string_without_embedded_nuls (Lisp_Object object)
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
{
|
|
|
|
CHECK_STRING (object);
|
|
|
|
CHECK_TYPE (memchr (SDATA (object), '\0', SBYTES (object)) == NULL,
|
|
|
|
Qstring_without_embedded_nulls_p, object);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Signal an error of type `json-out-of-memory' if OBJECT is
|
|
|
|
NULL. */
|
|
|
|
|
|
|
|
static json_t *
|
|
|
|
json_check (json_t *object)
|
|
|
|
{
|
|
|
|
if (object == NULL)
|
|
|
|
json_out_of_memory ();
|
|
|
|
return object;
|
|
|
|
}
|
|
|
|
|
2017-12-23 17:56:36 +01:00
|
|
|
/* If STRING is not a valid UTF-8 string, signal an error of type
|
|
|
|
`wrong-type-argument'. STRING must be a unibyte string. */
|
|
|
|
|
|
|
|
static void
|
|
|
|
json_check_utf8 (Lisp_Object string)
|
|
|
|
{
|
|
|
|
CHECK_TYPE (utf8_string_p (string), Qutf_8_string_p, string);
|
|
|
|
}
|
|
|
|
|
2018-06-08 02:35:50 +01:00
|
|
|
enum json_object_type {
|
|
|
|
json_object_hashtable,
|
|
|
|
json_object_alist,
|
|
|
|
json_object_plist
|
|
|
|
};
|
|
|
|
|
2019-04-13 01:33:05 +03:00
|
|
|
enum json_array_type {
|
|
|
|
json_array_array,
|
|
|
|
json_array_list
|
|
|
|
};
|
|
|
|
|
2018-06-08 02:35:50 +01:00
|
|
|
struct json_configuration {
|
|
|
|
enum json_object_type object_type;
|
2019-04-13 01:33:05 +03:00
|
|
|
enum json_array_type array_type;
|
2018-06-08 02:35:50 +01:00
|
|
|
Lisp_Object null_object;
|
|
|
|
Lisp_Object false_object;
|
|
|
|
};
|
|
|
|
|
|
|
|
static json_t *lisp_to_json (Lisp_Object, struct json_configuration *conf);
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
|
2018-06-09 17:56:29 -07:00
|
|
|
/* Convert a Lisp object to a toplevel JSON object (array or object). */
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
|
2018-06-09 17:56:29 -07:00
|
|
|
static json_t *
|
2018-06-08 02:35:50 +01:00
|
|
|
lisp_to_json_toplevel_1 (Lisp_Object lisp,
|
|
|
|
struct json_configuration *conf)
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
{
|
2018-06-09 17:56:29 -07:00
|
|
|
json_t *json;
|
|
|
|
ptrdiff_t count;
|
|
|
|
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
if (VECTORP (lisp))
|
|
|
|
{
|
|
|
|
ptrdiff_t size = ASIZE (lisp);
|
2018-06-09 17:56:29 -07:00
|
|
|
json = json_check (json_array ());
|
|
|
|
count = SPECPDL_INDEX ();
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
record_unwind_protect_ptr (json_release_object, json);
|
|
|
|
for (ptrdiff_t i = 0; i < size; ++i)
|
|
|
|
{
|
|
|
|
int status
|
2018-06-08 02:35:50 +01:00
|
|
|
= json_array_append_new (json, lisp_to_json (AREF (lisp, i),
|
|
|
|
conf));
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
if (status == -1)
|
|
|
|
json_out_of_memory ();
|
|
|
|
}
|
2018-06-09 17:56:29 -07:00
|
|
|
eassert (json_array_size (json) == size);
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
}
|
|
|
|
else if (HASH_TABLE_P (lisp))
|
|
|
|
{
|
|
|
|
struct Lisp_Hash_Table *h = XHASH_TABLE (lisp);
|
2018-06-09 17:56:29 -07:00
|
|
|
json = json_check (json_object ());
|
|
|
|
count = SPECPDL_INDEX ();
|
|
|
|
record_unwind_protect_ptr (json_release_object, json);
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
for (ptrdiff_t i = 0; i < HASH_TABLE_SIZE (h); ++i)
|
|
|
|
if (!NILP (HASH_HASH (h, i)))
|
|
|
|
{
|
|
|
|
Lisp_Object key = json_encode (HASH_KEY (h, i));
|
2017-12-14 19:53:58 +02:00
|
|
|
/* We can't specify the length, so the string must be
|
2019-03-21 23:55:28 -04:00
|
|
|
NUL-terminated. */
|
|
|
|
check_string_without_embedded_nuls (key);
|
2017-12-19 00:04:29 +01:00
|
|
|
const char *key_str = SSDATA (key);
|
|
|
|
/* Reject duplicate keys. These are possible if the hash
|
|
|
|
table test is not `equal'. */
|
2018-06-09 17:56:29 -07:00
|
|
|
if (json_object_get (json, key_str) != NULL)
|
2017-12-19 00:04:29 +01:00
|
|
|
wrong_type_argument (Qjson_value_p, lisp);
|
2018-06-09 17:56:29 -07:00
|
|
|
int status = json_object_set_new (json, key_str,
|
2018-06-08 02:35:50 +01:00
|
|
|
lisp_to_json (HASH_VALUE (h, i),
|
|
|
|
conf));
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
if (status == -1)
|
2017-12-23 17:56:36 +01:00
|
|
|
{
|
|
|
|
/* A failure can be caused either by an invalid key or
|
|
|
|
by low memory. */
|
|
|
|
json_check_utf8 (key);
|
|
|
|
json_out_of_memory ();
|
|
|
|
}
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
}
|
|
|
|
}
|
2017-12-13 22:41:28 +01:00
|
|
|
else if (NILP (lisp))
|
2018-06-09 17:56:29 -07:00
|
|
|
return json_check (json_object ());
|
2017-12-13 22:41:28 +01:00
|
|
|
else if (CONSP (lisp))
|
|
|
|
{
|
|
|
|
Lisp_Object tail = lisp;
|
2018-06-09 17:56:29 -07:00
|
|
|
json = json_check (json_object ());
|
|
|
|
count = SPECPDL_INDEX ();
|
|
|
|
record_unwind_protect_ptr (json_release_object, json);
|
2018-06-02 00:23:38 +01:00
|
|
|
bool is_plist = !CONSP (XCAR (tail));
|
2017-12-13 22:41:28 +01:00
|
|
|
FOR_EACH_TAIL (tail)
|
|
|
|
{
|
2018-06-02 00:23:38 +01:00
|
|
|
const char *key_str;
|
|
|
|
Lisp_Object value;
|
|
|
|
Lisp_Object key_symbol;
|
|
|
|
if (is_plist)
|
|
|
|
{
|
|
|
|
key_symbol = XCAR (tail);
|
|
|
|
tail = XCDR (tail);
|
|
|
|
CHECK_CONS (tail);
|
|
|
|
value = XCAR (tail);
|
|
|
|
if (EQ (tail, li.tortoise)) circular_list (lisp);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Lisp_Object pair = XCAR (tail);
|
|
|
|
CHECK_CONS (pair);
|
|
|
|
key_symbol = XCAR (pair);
|
|
|
|
value = XCDR (pair);
|
|
|
|
}
|
2017-12-13 22:41:28 +01:00
|
|
|
CHECK_SYMBOL (key_symbol);
|
|
|
|
Lisp_Object key = SYMBOL_NAME (key_symbol);
|
|
|
|
/* We can't specify the length, so the string must be
|
2019-03-21 23:55:28 -04:00
|
|
|
NUL-terminated. */
|
|
|
|
check_string_without_embedded_nuls (key);
|
2018-06-02 00:23:38 +01:00
|
|
|
key_str = SSDATA (key);
|
|
|
|
/* In plists, ensure leading ":" in keys is stripped. It
|
|
|
|
will be reconstructed later in `json_to_lisp'.*/
|
|
|
|
if (is_plist && ':' == key_str[0] && key_str[1])
|
|
|
|
{
|
|
|
|
key_str = &key_str[1];
|
|
|
|
}
|
2017-12-13 22:41:28 +01:00
|
|
|
/* Only add element if key is not already present. */
|
2018-06-09 17:56:29 -07:00
|
|
|
if (json_object_get (json, key_str) == NULL)
|
2017-12-13 22:41:28 +01:00
|
|
|
{
|
|
|
|
int status
|
2018-06-08 02:35:50 +01:00
|
|
|
= json_object_set_new (json, key_str, lisp_to_json (value,
|
|
|
|
conf));
|
2017-12-13 22:41:28 +01:00
|
|
|
if (status == -1)
|
|
|
|
json_out_of_memory ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_LIST_END (tail, lisp);
|
|
|
|
}
|
2018-06-09 17:56:29 -07:00
|
|
|
else
|
|
|
|
wrong_type_argument (Qjson_value_p, lisp);
|
|
|
|
|
|
|
|
clear_unwind_protect (count);
|
|
|
|
unbind_to (count, Qnil);
|
|
|
|
return json;
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Convert LISP to a toplevel JSON object (array or object). Signal
|
2017-12-13 22:41:28 +01:00
|
|
|
an error of type `wrong-type-argument' if LISP is not a vector,
|
2018-06-02 00:23:38 +01:00
|
|
|
hashtable, alist, or plist. */
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
|
|
|
|
static json_t *
|
2018-06-08 02:35:50 +01:00
|
|
|
lisp_to_json_toplevel (Lisp_Object lisp, struct json_configuration *conf)
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
{
|
|
|
|
if (++lisp_eval_depth > max_lisp_eval_depth)
|
|
|
|
xsignal0 (Qjson_object_too_deep);
|
2018-06-08 02:35:50 +01:00
|
|
|
json_t *json = lisp_to_json_toplevel_1 (lisp, conf);
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
--lisp_eval_depth;
|
|
|
|
return json;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Convert LISP to any JSON object. Signal an error of type
|
|
|
|
`wrong-type-argument' if the type of LISP can't be converted to a
|
|
|
|
JSON object. */
|
|
|
|
|
|
|
|
static json_t *
|
2018-06-08 02:35:50 +01:00
|
|
|
lisp_to_json (Lisp_Object lisp, struct json_configuration *conf)
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
{
|
2018-06-08 02:35:50 +01:00
|
|
|
if (EQ (lisp, conf->null_object))
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
return json_check (json_null ());
|
2018-06-08 02:35:50 +01:00
|
|
|
else if (EQ (lisp, conf->false_object))
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
return json_check (json_false ());
|
|
|
|
else if (EQ (lisp, Qt))
|
|
|
|
return json_check (json_true ());
|
2018-09-21 21:50:56 +02:00
|
|
|
else if (INTEGERP (lisp))
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
{
|
2018-09-21 21:50:56 +02:00
|
|
|
intmax_t low = TYPE_MINIMUM (json_int_t);
|
|
|
|
intmax_t high = TYPE_MAXIMUM (json_int_t);
|
|
|
|
intmax_t value;
|
|
|
|
if (! integer_to_intmax (lisp, &value) || value < low || high < value)
|
|
|
|
args_out_of_range_3 (lisp, make_int (low), make_int (high));
|
|
|
|
return json_check (json_integer (value));
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
}
|
|
|
|
else if (FLOATP (lisp))
|
|
|
|
return json_check (json_real (XFLOAT_DATA (lisp)));
|
|
|
|
else if (STRINGP (lisp))
|
|
|
|
{
|
|
|
|
Lisp_Object encoded = json_encode (lisp);
|
2017-12-23 17:56:36 +01:00
|
|
|
json_t *json = json_stringn (SSDATA (encoded), SBYTES (encoded));
|
|
|
|
if (json == NULL)
|
|
|
|
{
|
|
|
|
/* A failure can be caused either by an invalid string or by
|
|
|
|
low memory. */
|
|
|
|
json_check_utf8 (encoded);
|
|
|
|
json_out_of_memory ();
|
|
|
|
}
|
|
|
|
return json;
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
}
|
|
|
|
|
2018-06-02 00:23:38 +01:00
|
|
|
/* LISP now must be a vector, hashtable, alist, or plist. */
|
2018-06-08 02:35:50 +01:00
|
|
|
return lisp_to_json_toplevel (lisp, conf);
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
}
|
|
|
|
|
2018-06-08 02:35:50 +01:00
|
|
|
static void
|
|
|
|
json_parse_args (ptrdiff_t nargs,
|
|
|
|
Lisp_Object *args,
|
|
|
|
struct json_configuration *conf,
|
2019-04-13 01:33:05 +03:00
|
|
|
bool parse_object_types)
|
2018-06-08 02:35:50 +01:00
|
|
|
{
|
|
|
|
if ((nargs % 2) != 0)
|
|
|
|
wrong_type_argument (Qplistp, Flist (nargs, args));
|
|
|
|
|
|
|
|
/* Start from the back so keyword values appearing
|
|
|
|
first take precedence. */
|
|
|
|
for (ptrdiff_t i = nargs; i > 0; i -= 2) {
|
|
|
|
Lisp_Object key = args[i - 2];
|
|
|
|
Lisp_Object value = args[i - 1];
|
2019-04-13 01:33:05 +03:00
|
|
|
if (parse_object_types && EQ (key, QCobject_type))
|
2018-06-08 02:35:50 +01:00
|
|
|
{
|
|
|
|
if (EQ (value, Qhash_table))
|
|
|
|
conf->object_type = json_object_hashtable;
|
|
|
|
else if (EQ (value, Qalist))
|
|
|
|
conf->object_type = json_object_alist;
|
|
|
|
else if (EQ (value, Qplist))
|
|
|
|
conf->object_type = json_object_plist;
|
|
|
|
else
|
|
|
|
wrong_choice (list3 (Qhash_table, Qalist, Qplist), value);
|
|
|
|
}
|
2019-04-13 01:33:05 +03:00
|
|
|
else if (parse_object_types && EQ (key, QCarray_type))
|
|
|
|
{
|
|
|
|
if (EQ (value, Qarray))
|
|
|
|
conf->array_type = json_array_array;
|
|
|
|
else if (EQ (value, Qlist))
|
|
|
|
conf->array_type = json_array_list;
|
|
|
|
else
|
|
|
|
wrong_choice (list2 (Qarray, Qlist), value);
|
|
|
|
}
|
2018-06-08 02:35:50 +01:00
|
|
|
else if (EQ (key, QCnull_object))
|
|
|
|
conf->null_object = value;
|
|
|
|
else if (EQ (key, QCfalse_object))
|
|
|
|
conf->false_object = value;
|
2019-04-13 01:33:05 +03:00
|
|
|
else if (parse_object_types)
|
|
|
|
wrong_choice (list4 (QCobject_type,
|
|
|
|
QCarray_type,
|
2018-06-08 02:35:50 +01:00
|
|
|
QCnull_object,
|
|
|
|
QCfalse_object),
|
|
|
|
value);
|
|
|
|
else
|
|
|
|
wrong_choice (list2 (QCnull_object,
|
|
|
|
QCfalse_object),
|
|
|
|
value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN ("json-serialize", Fjson_serialize, Sjson_serialize, 1, MANY,
|
|
|
|
NULL,
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
doc: /* Return the JSON representation of OBJECT as a string.
|
2018-06-08 02:35:50 +01:00
|
|
|
|
2018-06-02 00:23:38 +01:00
|
|
|
OBJECT must be a vector, hashtable, alist, or plist and its elements
|
2018-06-08 02:35:50 +01:00
|
|
|
can recursively contain the Lisp equivalents to the JSON null and
|
|
|
|
false values, t, numbers, strings, or other vectors hashtables, alists
|
|
|
|
or plists. t will be converted to the JSON true value. Vectors will
|
|
|
|
be converted to JSON arrays, whereas hashtables, alists and plists are
|
|
|
|
converted to JSON objects. Hashtable keys must be strings without
|
2019-03-21 23:55:28 -04:00
|
|
|
embedded NUL characters and must be unique within each object. Alist
|
2018-06-08 02:35:50 +01:00
|
|
|
and plist keys must be symbols; if a key is duplicate, the first
|
|
|
|
instance is used.
|
|
|
|
|
|
|
|
The Lisp equivalents to the JSON null and false values are
|
|
|
|
configurable in the arguments ARGS, a list of keyword/argument pairs:
|
|
|
|
|
|
|
|
The keyword argument `:null-object' specifies which object to use
|
|
|
|
to represent a JSON null value. It defaults to `:null'.
|
|
|
|
|
|
|
|
The keyword argument `:false-object' specifies which object to use to
|
|
|
|
represent a JSON false value. It defaults to `:false'.
|
|
|
|
|
|
|
|
In you specify the same value for `:null-object' and `:false-object',
|
|
|
|
a potentially ambiguous situation, the JSON output will not contain
|
|
|
|
any JSON false values.
|
2018-06-16 13:40:38 +03:00
|
|
|
usage: (json-serialize OBJECT &rest ARGS) */)
|
2018-06-08 02:35:50 +01:00
|
|
|
(ptrdiff_t nargs, Lisp_Object *args)
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
{
|
|
|
|
ptrdiff_t count = SPECPDL_INDEX ();
|
|
|
|
|
2017-12-10 18:36:37 +02:00
|
|
|
#ifdef WINDOWSNT
|
|
|
|
if (!json_initialized)
|
|
|
|
{
|
|
|
|
Lisp_Object status;
|
|
|
|
json_initialized = init_json_functions ();
|
|
|
|
status = json_initialized ? Qt : Qnil;
|
|
|
|
Vlibrary_cache = Fcons (Fcons (Qjson, status), Vlibrary_cache);
|
|
|
|
}
|
|
|
|
if (!json_initialized)
|
|
|
|
{
|
|
|
|
message1 ("jansson library not found");
|
|
|
|
return Qnil;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2019-04-13 01:33:05 +03:00
|
|
|
struct json_configuration conf =
|
|
|
|
{json_object_hashtable, json_array_array, QCnull, QCfalse};
|
2018-06-08 02:35:50 +01:00
|
|
|
json_parse_args (nargs - 1, args + 1, &conf, false);
|
|
|
|
|
|
|
|
json_t *json = lisp_to_json_toplevel (args[0], &conf);
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
record_unwind_protect_ptr (json_release_object, json);
|
|
|
|
|
2017-12-19 00:03:05 +01:00
|
|
|
/* If desired, we might want to add the following flags:
|
|
|
|
JSON_DECODE_ANY, JSON_ALLOW_NUL. */
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
char *string = json_dumps (json, JSON_COMPACT);
|
|
|
|
if (string == NULL)
|
|
|
|
json_out_of_memory ();
|
2018-08-07 17:28:35 +03:00
|
|
|
record_unwind_protect_ptr (json_free, string);
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
|
|
|
|
return unbind_to (count, json_build_string (string));
|
|
|
|
}
|
|
|
|
|
|
|
|
struct json_buffer_and_size
|
|
|
|
{
|
|
|
|
const char *buffer;
|
|
|
|
ptrdiff_t size;
|
2018-10-13 10:13:10 +03:00
|
|
|
/* This tracks how many bytes were inserted by the callback since
|
|
|
|
json_dump_callback was called. */
|
|
|
|
ptrdiff_t inserted_bytes;
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
static Lisp_Object
|
|
|
|
json_insert (void *data)
|
|
|
|
{
|
|
|
|
struct json_buffer_and_size *buffer_and_size = data;
|
2018-10-13 10:13:10 +03:00
|
|
|
ptrdiff_t len = buffer_and_size->size;
|
|
|
|
ptrdiff_t inserted_bytes = buffer_and_size->inserted_bytes;
|
|
|
|
ptrdiff_t gap_size = GAP_SIZE - inserted_bytes;
|
|
|
|
|
|
|
|
/* Enlarge the gap if necessary. */
|
|
|
|
if (gap_size < len)
|
|
|
|
make_gap (len - gap_size);
|
|
|
|
|
|
|
|
/* Copy this chunk of data into the gap. */
|
|
|
|
memcpy ((char *) BEG_ADDR + PT_BYTE - BEG_BYTE + inserted_bytes,
|
|
|
|
buffer_and_size->buffer, len);
|
|
|
|
buffer_and_size->inserted_bytes += len;
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
return Qnil;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct json_insert_data
|
|
|
|
{
|
2018-10-13 10:13:10 +03:00
|
|
|
/* This tracks how many bytes were inserted by the callback since
|
|
|
|
json_dump_callback was called. */
|
|
|
|
ptrdiff_t inserted_bytes;
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
/* nil if json_insert succeeded, otherwise the symbol
|
|
|
|
Qcatch_all_memory_full or a cons (ERROR-SYMBOL . ERROR-DATA). */
|
|
|
|
Lisp_Object error;
|
|
|
|
};
|
|
|
|
|
2018-10-13 10:13:10 +03:00
|
|
|
/* Callback for json_dump_callback that inserts a JSON representation
|
|
|
|
as a unibyte string into the gap. DATA must point to a structure
|
|
|
|
of type json_insert_data. This function may not exit nonlocally.
|
|
|
|
It catches all nonlocal exits and stores them in data->error for
|
|
|
|
reraising. */
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
|
|
|
|
static int
|
|
|
|
json_insert_callback (const char *buffer, size_t size, void *data)
|
|
|
|
{
|
|
|
|
struct json_insert_data *d = data;
|
|
|
|
struct json_buffer_and_size buffer_and_size
|
2018-10-13 10:13:10 +03:00
|
|
|
= {.buffer = buffer, .size = size, .inserted_bytes = d->inserted_bytes};
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
d->error = internal_catch_all (json_insert, &buffer_and_size, Fidentity);
|
2018-10-13 10:13:10 +03:00
|
|
|
d->inserted_bytes = buffer_and_size.inserted_bytes;
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
return NILP (d->error) ? 0 : -1;
|
|
|
|
}
|
|
|
|
|
2018-06-08 02:35:50 +01:00
|
|
|
DEFUN ("json-insert", Fjson_insert, Sjson_insert, 1, MANY,
|
|
|
|
NULL,
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
doc: /* Insert the JSON representation of OBJECT before point.
|
2018-06-08 02:35:50 +01:00
|
|
|
This is the same as (insert (json-serialize OBJECT)), but potentially
|
|
|
|
faster. See the function `json-serialize' for allowed values of
|
2018-06-16 13:40:38 +03:00
|
|
|
OBJECT.
|
|
|
|
usage: (json-insert OBJECT &rest ARGS) */)
|
2018-06-08 02:35:50 +01:00
|
|
|
(ptrdiff_t nargs, Lisp_Object *args)
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
{
|
|
|
|
ptrdiff_t count = SPECPDL_INDEX ();
|
|
|
|
|
2017-12-10 18:36:37 +02:00
|
|
|
#ifdef WINDOWSNT
|
|
|
|
if (!json_initialized)
|
|
|
|
{
|
|
|
|
Lisp_Object status;
|
|
|
|
json_initialized = init_json_functions ();
|
|
|
|
status = json_initialized ? Qt : Qnil;
|
|
|
|
Vlibrary_cache = Fcons (Fcons (Qjson, status), Vlibrary_cache);
|
|
|
|
}
|
|
|
|
if (!json_initialized)
|
|
|
|
{
|
|
|
|
message1 ("jansson library not found");
|
|
|
|
return Qnil;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2019-04-13 01:33:05 +03:00
|
|
|
struct json_configuration conf =
|
|
|
|
{json_object_hashtable, json_array_array, QCnull, QCfalse};
|
2018-06-08 02:35:50 +01:00
|
|
|
json_parse_args (nargs - 1, args + 1, &conf, false);
|
|
|
|
|
|
|
|
json_t *json = lisp_to_json (args[0], &conf);
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
record_unwind_protect_ptr (json_release_object, json);
|
|
|
|
|
2018-10-13 10:13:10 +03:00
|
|
|
prepare_to_modify_buffer (PT, PT, NULL);
|
|
|
|
move_gap_both (PT, PT_BYTE);
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
struct json_insert_data data;
|
2018-10-13 10:13:10 +03:00
|
|
|
data.inserted_bytes = 0;
|
2017-12-19 00:03:05 +01:00
|
|
|
/* If desired, we might want to add the following flags:
|
|
|
|
JSON_DECODE_ANY, JSON_ALLOW_NUL. */
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
int status
|
2018-10-13 10:13:10 +03:00
|
|
|
/* Could have used json_dumpb, but that became available only in
|
|
|
|
Jansson 2.10, whereas we want to support 2.7 and upward. */
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
= json_dump_callback (json, json_insert_callback, &data, JSON_COMPACT);
|
|
|
|
if (status == -1)
|
|
|
|
{
|
|
|
|
if (CONSP (data.error))
|
|
|
|
xsignal (XCAR (data.error), XCDR (data.error));
|
|
|
|
else
|
|
|
|
json_out_of_memory ();
|
|
|
|
}
|
|
|
|
|
2018-10-13 10:13:10 +03:00
|
|
|
ptrdiff_t inserted = 0;
|
|
|
|
ptrdiff_t inserted_bytes = data.inserted_bytes;
|
|
|
|
if (inserted_bytes > 0)
|
|
|
|
{
|
|
|
|
/* Make the inserted text part of the buffer, as unibyte text. */
|
|
|
|
GAP_SIZE -= inserted_bytes;
|
|
|
|
GPT += inserted_bytes;
|
|
|
|
GPT_BYTE += inserted_bytes;
|
|
|
|
ZV += inserted_bytes;
|
|
|
|
ZV_BYTE += inserted_bytes;
|
|
|
|
Z += inserted_bytes;
|
|
|
|
Z_BYTE += inserted_bytes;
|
|
|
|
|
|
|
|
if (GAP_SIZE > 0)
|
|
|
|
/* Put an anchor to ensure multi-byte form ends at gap. */
|
|
|
|
*GPT_ADDR = 0;
|
|
|
|
|
|
|
|
/* If required, decode the stuff we've read into the gap. */
|
|
|
|
struct coding_system coding;
|
|
|
|
/* JSON strings are UTF-8 encoded strings. If for some reason
|
|
|
|
the text returned by the Jansson library includes invalid
|
|
|
|
byte sequences, they will be represented by raw bytes in the
|
|
|
|
buffer text. */
|
|
|
|
setup_coding_system (Qutf_8_unix, &coding);
|
|
|
|
coding.dst_multibyte =
|
|
|
|
!NILP (BVAR (current_buffer, enable_multibyte_characters));
|
|
|
|
if (CODING_MAY_REQUIRE_DECODING (&coding))
|
|
|
|
{
|
|
|
|
move_gap_both (PT, PT_BYTE);
|
|
|
|
GAP_SIZE += inserted_bytes;
|
|
|
|
ZV_BYTE -= inserted_bytes;
|
|
|
|
Z_BYTE -= inserted_bytes;
|
|
|
|
ZV -= inserted_bytes;
|
|
|
|
Z -= inserted_bytes;
|
|
|
|
decode_coding_gap (&coding, inserted_bytes, inserted_bytes);
|
|
|
|
inserted = coding.produced_char;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* The target buffer is unibyte, so we don't need to decode. */
|
|
|
|
invalidate_buffer_caches (current_buffer,
|
|
|
|
PT, PT + inserted_bytes);
|
|
|
|
adjust_after_insert (PT, PT_BYTE,
|
|
|
|
PT + inserted_bytes,
|
|
|
|
PT_BYTE + inserted_bytes,
|
|
|
|
inserted_bytes);
|
|
|
|
inserted = inserted_bytes;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Call after-change hooks. */
|
|
|
|
signal_after_change (PT, 0, inserted);
|
|
|
|
if (inserted > 0)
|
|
|
|
{
|
|
|
|
update_compositions (PT, PT, CHECK_BORDER);
|
|
|
|
/* Move point to after the inserted text. */
|
|
|
|
SET_PT_BOTH (PT + inserted, PT_BYTE + inserted_bytes);
|
|
|
|
}
|
|
|
|
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
return unbind_to (count, Qnil);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Convert a JSON object to a Lisp object. */
|
|
|
|
|
Modularize bignums better
* src/bignum.c, src/bignum.h: New files. Only modules that
need to know how bignums are implemented should include
bignum.h. Currently these are alloc.c, bignum.c (of course),
data.c, emacs.c, emacs-module.c, floatfns.c, fns.c, print.c.
* src/Makefile.in (base_obj): Add bignum.o.
* src/alloc.c (make_bignum_str): Move to bignum.c.
(make_number): Remove; replaced by bignum.c’s make_integer.
All callers changed.
* src/conf_post.h (ARG_NONNULL): New macro.
* src/json.c (json_to_lisp): Use it.
* src/data.c (Fnatnump):
Move NATNUMP’s implementation here from lisp.h.
* src/data.c (Fnumber_to_string):
* src/editfns.c (styled_format):
Move conversion of string to bignum to bignum_to_string, and
call it here.
* src/emacs-module.c (module_make_integer):
* src/floatfns.c (Fabs):
Simplify by using make_int.
* src/emacs.c: Include bignum.h, to expand its inline fns.
* src/floatfns.c (Ffloat): Simplify by using XFLOATINT.
(rounding_driver): Simplify by using double_to_bignum.
(rounddiv_q): Clarify use of temporaries.
* src/lisp.h: Move decls that need to know bignum internals to
bignum.h. Do not include gmp.h or mini-gmp.h; that is now
bignum.h’s job.
(GMP_NUM_BITS, struct Lisp_Bignum, XBIGNUM, mpz_set_intmax):
Move to bignum.h.
(make_int): New function.
(NATNUMP): Remove; all callers changed to use Fnatnump.
(XFLOATINT): If arg is a bignum, use bignum_to_double, so that
bignum internals are not exposed here.
* src/print.c (print_vectorlike): Use SAFE_ALLOCA to avoid the
need for a record_unwind_protect_ptr.
2018-08-27 21:27:50 -07:00
|
|
|
static Lisp_Object ARG_NONNULL ((1))
|
2018-06-07 17:41:19 +01:00
|
|
|
json_to_lisp (json_t *json, struct json_configuration *conf)
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
{
|
|
|
|
switch (json_typeof (json))
|
|
|
|
{
|
|
|
|
case JSON_NULL:
|
2018-06-07 17:41:19 +01:00
|
|
|
return conf->null_object;
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
case JSON_FALSE:
|
2018-06-07 17:41:19 +01:00
|
|
|
return conf->false_object;
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
case JSON_TRUE:
|
|
|
|
return Qt;
|
|
|
|
case JSON_INTEGER:
|
Improve bignum support for system types
Use bignums when Emacs converts to and from system types like
off_t for file sizes whose values can exceed fixnum range.
Formerly, Emacs sometimes generted floats and sometimes ad-hoc
conses of integers. Emacs still accepts floats and conses for
these system types, in case some stray Lisp code is generating
them, though this usage is obsolescent.
* doc/lispref/files.texi (File Attributes):
* doc/lispref/hash.texi (Defining Hash):
* doc/lispref/nonascii.texi (Character Sets):
* doc/lispref/os.texi (User Identification):
* doc/lispref/processes.texi (System Processes):
* etc/NEWS:
Document changes.
* src/bignum.c (mpz_set_uintmax, make_biguint)
(mpz_set_uintmax_slow, bignum_to_intmax, bignum_to_uintmax):
New functions.
(mpz_set_intmax_slow): Implement via mpz_limbs_write,
to avoid the need for an extra pass through a negative number.
* src/charset.c (Fencode_char):
* src/composite.h (LGLYPH_SET_CODE):
* src/dired.c (file_attributes):
* src/dosfns.c, src/w32.c (list_system_processes)
(system_process_attributes):
* src/editfns.c (init_editfns, Fuser_uid, Fuser_real_uid)
(Fgroup_gid, Fgroup_real_gid, Femacs_pid):
* src/emacs-module.c (check_vec_index):
* src/fns.c (Fsafe_length):
* src/process.c (record_deleted_pid, Fprocess_id):
* src/sysdep.c (list_system_processes, system_process_attributes):
* src/xselect.c (x_own_selection, selection_data_to_lisp_data):
* src/xterm.c (set_wm_state):
* src/inotify.c (inotifyevent_to_event, add_watch)
(inotify_callback):
If an integer is out of fixnum range, use a bignum
instead of converting it to a float or a cons of integers.
* src/coding.c (Fdefine_coding_system_internal):
* src/frame.c (frame_windows_min_size)
(x_set_frame_parameters):
* src/fringe.c (Fdefine_fringe_bitmap):
* src/nsterm.m (mouseDown:):
* src/syntax.c (find_defun_start):
* src/w32fns.c (x_set_undecorated, w32_createwindow)
(w32_wnd_proc, Fx_create_frame, Fx_show_tip)
(w32_console_toggle_lock_key):
* src/w32inevt.c (key_event):
* src/w32proc.c (Fw32_get_locale_info):
Do not mishandle floats by treating their addresses as their
values.
* src/data.c (store_symval_forwarding):
* src/gnutls.c (Fgnutls_error_fatalp, Fgnutls_error_string):
* src/keyboard.c (command_loop_1, make_lispy_event):
* src/lread.c (read_filtered_event, read1)
(substitute_object_recurse):
* src/window.c (Fcoordinates_in_window_p, Fwindow_at)
(window_resize_apply, Fset_window_vscroll):
* src/xdisp.c (handle_single_display_spec, try_scrolling)
(redisplay_window, calc_pixel_width_or_height)
(calc_line_height_property, on_hot_spot_p):
* src/xfaces.c (check_lface_attrs):
* src/xselect.c (x_get_local_selection, cons_to_x_long)
(lisp_data_to_selection_data, clean_local_selection_data)
(x_check_property_data, x_fill_property_data):
(x_send_client_event):
Do not reject bignums.
* src/data.c (INTBIG_TO_LISP, intbig_to_lisp)
(uintbig_to_lisp):
Remove. All uses removed.
* src/data.c (cons_to_unsigned, cons_to_signed):
* src/dbusbind.c (xd_signature, xd_extract_signed)
(xd_extract_unsigned):
* src/dispnew.c (sit_for):
* src/dosfns.c, src/w32.c (system_process_attributes):
* src/editfns.c (Fuser_full_name):
* src/fileio.c (file_offset):
* src/fileio.c (write_region):
* src/font.c (font_unparse_xlfd, font_open_for_lface, Fopen_font):
* src/frame.c (x_set_screen_gamma):
* src/frame.h (NUMVAL, FRAME_PIXEL_X_FROM_CANON_X)
(FRAME_PIXEL_Y_FROM_CANON_Y):
* src/image.c (parse_image_spec, x_edge_detection)
(compute_image_size):
* src/json.c (json_to_lisp):
* src/lcms.c (PARSE_LAB_LIST_FIELD, Flcms_cie_de2000)
(PARSE_XYZ_LIST_FIELD, PARSE_JCH_LIST_FIELD)
(PARSE_JAB_LIST_FIELD, PARSE_VIEW_CONDITION_FLOAT)
(Flcms_temp_to_white_point):
* src/nsimage.m (ns_load_image, setSizeFromSpec):
* src/process.c (Fsignal_process, handle_child_signal):
* src/sysdep.c (system_process_attributes):
* src/xdisp.c (calc_line_height_property):
Handle bignums.
* src/data.c (Fnumber_to_string): Use proper predicate name in
signal if the argument is not a number.
* src/lisp.h (make_uint): New function.
(INT_TO_INTEGER): New macro.
(FIXED_OR_FLOATP, CHECK_FIXNUM_OR_FLOAT)
(CHECK_FIXNUM_OR_FLOAT_COERCE_MARKER, INTEGER_TO_CONS)
(make_fixnum_or_float): Remove; no longer used.
* src/nsfns.m, src/w32fns.c, src/xfns.c (Fx_create_frame):
Reject floating-point min-width or min-height.
* src/process.c (handle_child_signal): Do not worry
about floating-point pids, as they are no longer generated.
2018-08-27 21:27:50 -07:00
|
|
|
{
|
|
|
|
json_int_t i = json_integer_value (json);
|
|
|
|
return INT_TO_INTEGER (i);
|
|
|
|
}
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
case JSON_REAL:
|
|
|
|
return make_float (json_real_value (json));
|
|
|
|
case JSON_STRING:
|
|
|
|
return json_make_string (json_string_value (json),
|
|
|
|
json_string_length (json));
|
|
|
|
case JSON_ARRAY:
|
|
|
|
{
|
|
|
|
if (++lisp_eval_depth > max_lisp_eval_depth)
|
|
|
|
xsignal0 (Qjson_object_too_deep);
|
|
|
|
size_t size = json_array_size (json);
|
2018-12-31 23:07:33 -08:00
|
|
|
if (PTRDIFF_MAX < size)
|
2018-09-21 21:56:25 +02:00
|
|
|
overflow_error ();
|
2019-04-13 01:33:05 +03:00
|
|
|
Lisp_Object result;
|
|
|
|
switch (conf->array_type)
|
|
|
|
{
|
|
|
|
case json_array_array:
|
|
|
|
{
|
|
|
|
result = make_vector (size, Qunbound);
|
|
|
|
for (ptrdiff_t i = 0; i < size; ++i)
|
|
|
|
{
|
|
|
|
rarely_quit (i);
|
|
|
|
ASET (result, i,
|
|
|
|
json_to_lisp (json_array_get (json, i), conf));
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case json_array_list:
|
|
|
|
{
|
|
|
|
result = Qnil;
|
|
|
|
for (ptrdiff_t i = size - 1; i >= 0; --i)
|
|
|
|
{
|
|
|
|
rarely_quit (i);
|
|
|
|
result = Fcons (json_to_lisp (json_array_get (json, i), conf),
|
|
|
|
result);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
/* Can't get here. */
|
|
|
|
emacs_abort ();
|
|
|
|
}
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
--lisp_eval_depth;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
case JSON_OBJECT:
|
|
|
|
{
|
|
|
|
if (++lisp_eval_depth > max_lisp_eval_depth)
|
|
|
|
xsignal0 (Qjson_object_too_deep);
|
2017-12-13 23:35:07 +01:00
|
|
|
Lisp_Object result;
|
2018-06-07 17:41:19 +01:00
|
|
|
switch (conf->object_type)
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
{
|
2017-12-13 23:35:07 +01:00
|
|
|
case json_object_hashtable:
|
|
|
|
{
|
|
|
|
size_t size = json_object_size (json);
|
|
|
|
if (FIXNUM_OVERFLOW_P (size))
|
2018-09-21 21:56:25 +02:00
|
|
|
overflow_error ();
|
2017-12-13 23:35:07 +01:00
|
|
|
result = CALLN (Fmake_hash_table, QCtest, Qequal, QCsize,
|
Rename integerp->fixnum, etc, in preparation for bignums
* src/json.c, src/keyboard.c, src/keyboard.h, src/keymap.c,
src/kqueue.c, src/lcms.c, src/lisp.h, src/lread.c, src/macros.c,
src/marker.c, src/menu.c, src/minibuf.c, src/msdos.c, src/print.c,
src/process.c, src/profiler.c, src/search.c, src/sound.c,
src/syntax.c, src/sysdep.c, src/term.c, src/terminal.c,
src/textprop.c, src/undo.c, src/w16select.c, src/w32.c,
src/w32console.c, src/w32cygwinx.c, src/w32fns.c, src/w32font.c,
src/w32inevt.c, src/w32proc.c, src/w32select.c, src/w32term.c,
src/w32uniscribe.c, src/widget.c, src/window.c, src/xdisp.c,
src/xfaces.c, src/xfns.c, src/xfont.c, src/xftfont.c, src/xmenu.c,
src/xrdb.c, src/xselect.c, src/xterm.c, src/xwidget.c: Rename
INTEGERP->FIXNUM, make_number->make_fixnum, CHECK_NUMBER->CHECK_FIXNUM,
make_natnum->make_fixed_natum, NUMBERP->FIXED_OR_FLOATP,
NATNUMP->FIXNATP, CHECK_NATNUM->CHECK_FIXNAT.
2018-07-06 21:56:17 -06:00
|
|
|
make_fixed_natnum (size));
|
2017-12-13 23:35:07 +01:00
|
|
|
struct Lisp_Hash_Table *h = XHASH_TABLE (result);
|
|
|
|
const char *key_str;
|
|
|
|
json_t *value;
|
|
|
|
json_object_foreach (json, key_str, value)
|
|
|
|
{
|
|
|
|
Lisp_Object key = json_build_string (key_str);
|
|
|
|
EMACS_UINT hash;
|
|
|
|
ptrdiff_t i = hash_lookup (h, key, &hash);
|
|
|
|
/* Keys in JSON objects are unique, so the key can't
|
|
|
|
be present yet. */
|
|
|
|
eassert (i < 0);
|
2018-06-07 17:41:19 +01:00
|
|
|
hash_put (h, key, json_to_lisp (value, conf), hash);
|
2017-12-13 23:35:07 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case json_object_alist:
|
|
|
|
{
|
|
|
|
result = Qnil;
|
|
|
|
const char *key_str;
|
|
|
|
json_t *value;
|
|
|
|
json_object_foreach (json, key_str, value)
|
|
|
|
{
|
|
|
|
Lisp_Object key = Fintern (json_build_string (key_str), Qnil);
|
|
|
|
result
|
2018-06-07 17:41:19 +01:00
|
|
|
= Fcons (Fcons (key, json_to_lisp (value, conf)),
|
2017-12-13 23:35:07 +01:00
|
|
|
result);
|
|
|
|
}
|
|
|
|
result = Fnreverse (result);
|
|
|
|
break;
|
|
|
|
}
|
2018-06-02 00:23:38 +01:00
|
|
|
case json_object_plist:
|
|
|
|
{
|
|
|
|
result = Qnil;
|
|
|
|
const char *key_str;
|
|
|
|
json_t *value;
|
|
|
|
json_object_foreach (json, key_str, value)
|
|
|
|
{
|
|
|
|
USE_SAFE_ALLOCA;
|
|
|
|
ptrdiff_t key_str_len = strlen (key_str);
|
|
|
|
char *keyword_key_str = SAFE_ALLOCA (1 + key_str_len + 1);
|
|
|
|
keyword_key_str[0] = ':';
|
|
|
|
strcpy (&keyword_key_str[1], key_str);
|
|
|
|
Lisp_Object key = intern_1 (keyword_key_str, key_str_len + 1);
|
|
|
|
/* Build the plist as value-key since we're going to
|
|
|
|
reverse it in the end.*/
|
|
|
|
result = Fcons (key, result);
|
2018-06-07 17:41:19 +01:00
|
|
|
result = Fcons (json_to_lisp (value, conf), result);
|
2018-06-02 00:23:38 +01:00
|
|
|
SAFE_FREE ();
|
|
|
|
}
|
|
|
|
result = Fnreverse (result);
|
|
|
|
break;
|
|
|
|
}
|
2017-12-13 23:35:07 +01:00
|
|
|
default:
|
|
|
|
/* Can't get here. */
|
|
|
|
emacs_abort ();
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
}
|
|
|
|
--lisp_eval_depth;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
2017-12-14 19:53:58 +02:00
|
|
|
/* Can't get here. */
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
emacs_abort ();
|
|
|
|
}
|
|
|
|
|
2017-12-13 23:35:07 +01:00
|
|
|
DEFUN ("json-parse-string", Fjson_parse_string, Sjson_parse_string, 1, MANY,
|
|
|
|
NULL,
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
doc: /* Parse the JSON STRING into a Lisp object.
|
|
|
|
This is essentially the reverse operation of `json-serialize', which
|
2019-04-13 10:07:15 +03:00
|
|
|
see. The returned object will be a vector, list, hashtable, alist, or
|
2018-06-07 17:41:19 +01:00
|
|
|
plist. Its elements will be the JSON null value, the JSON false
|
|
|
|
value, t, numbers, strings, or further vectors, hashtables, alists, or
|
|
|
|
plists. If there are duplicate keys in an object, all but the last
|
2019-04-13 10:07:15 +03:00
|
|
|
one are ignored. If STRING doesn't contain a valid JSON object, this
|
|
|
|
function signals an error of type `json-parse-error'.
|
|
|
|
|
|
|
|
The arguments ARGS are a list of keyword/argument pairs:
|
2018-06-07 17:41:19 +01:00
|
|
|
|
|
|
|
The keyword argument `:object-type' specifies which Lisp type is used
|
2019-04-13 01:33:05 +03:00
|
|
|
to represent objects; it can be `hash-table', `alist' or `plist'. It
|
|
|
|
defaults to `hash-table'.
|
|
|
|
|
|
|
|
The keyword argument `:array-type' specifies which Lisp type is used
|
2019-04-13 10:07:15 +03:00
|
|
|
to represent arrays; it can be `array' (the default) or `list'.
|
2018-06-07 17:41:19 +01:00
|
|
|
|
|
|
|
The keyword argument `:null-object' specifies which object to use
|
|
|
|
to represent a JSON null value. It defaults to `:null'.
|
|
|
|
|
|
|
|
The keyword argument `:false-object' specifies which object to use to
|
|
|
|
represent a JSON false value. It defaults to `:false'.
|
2018-06-08 02:35:50 +01:00
|
|
|
usage: (json-parse-string STRING &rest ARGS) */)
|
|
|
|
(ptrdiff_t nargs, Lisp_Object *args)
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
{
|
|
|
|
ptrdiff_t count = SPECPDL_INDEX ();
|
2017-12-10 18:36:37 +02:00
|
|
|
|
|
|
|
#ifdef WINDOWSNT
|
|
|
|
if (!json_initialized)
|
|
|
|
{
|
|
|
|
Lisp_Object status;
|
|
|
|
json_initialized = init_json_functions ();
|
|
|
|
status = json_initialized ? Qt : Qnil;
|
|
|
|
Vlibrary_cache = Fcons (Fcons (Qjson, status), Vlibrary_cache);
|
|
|
|
}
|
|
|
|
if (!json_initialized)
|
|
|
|
{
|
|
|
|
message1 ("jansson library not found");
|
|
|
|
return Qnil;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2017-12-13 23:35:07 +01:00
|
|
|
Lisp_Object string = args[0];
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
Lisp_Object encoded = json_encode (string);
|
2019-03-21 23:55:28 -04:00
|
|
|
check_string_without_embedded_nuls (encoded);
|
2019-04-13 01:33:05 +03:00
|
|
|
struct json_configuration conf =
|
|
|
|
{json_object_hashtable, json_array_array, QCnull, QCfalse};
|
2018-06-08 02:35:50 +01:00
|
|
|
json_parse_args (nargs - 1, args + 1, &conf, true);
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
|
|
|
|
json_error_t error;
|
|
|
|
json_t *object = json_loads (SSDATA (encoded), 0, &error);
|
|
|
|
if (object == NULL)
|
|
|
|
json_parse_error (&error);
|
|
|
|
|
|
|
|
/* Avoid leaking the object in case of further errors. */
|
|
|
|
if (object != NULL)
|
|
|
|
record_unwind_protect_ptr (json_release_object, object);
|
|
|
|
|
2018-06-07 17:41:19 +01:00
|
|
|
return unbind_to (count, json_to_lisp (object, &conf));
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
struct json_read_buffer_data
|
|
|
|
{
|
|
|
|
/* Byte position of position to read the next chunk from. */
|
|
|
|
ptrdiff_t point;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Callback for json_load_callback that reads from the current buffer.
|
|
|
|
DATA must point to a structure of type json_read_buffer_data.
|
|
|
|
data->point must point to the byte position to read from; after
|
|
|
|
reading, data->point is advanced accordingly. The buffer point
|
|
|
|
itself is ignored. This function may not exit nonlocally. */
|
|
|
|
|
|
|
|
static size_t
|
|
|
|
json_read_buffer_callback (void *buffer, size_t buflen, void *data)
|
|
|
|
{
|
|
|
|
struct json_read_buffer_data *d = data;
|
|
|
|
|
|
|
|
/* First, parse from point to the gap or the end of the accessible
|
|
|
|
portion, whatever is closer. */
|
|
|
|
ptrdiff_t point = d->point;
|
|
|
|
ptrdiff_t end = BUFFER_CEILING_OF (point) + 1;
|
|
|
|
ptrdiff_t count = end - point;
|
|
|
|
if (buflen < count)
|
|
|
|
count = buflen;
|
|
|
|
memcpy (buffer, BYTE_POS_ADDR (point), count);
|
|
|
|
d->point += count;
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN ("json-parse-buffer", Fjson_parse_buffer, Sjson_parse_buffer,
|
2017-12-13 23:35:07 +01:00
|
|
|
0, MANY, NULL,
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
doc: /* Read JSON object from current buffer starting at point.
|
2019-04-13 10:07:15 +03:00
|
|
|
Move point after the end of the object if parsing was successful.
|
|
|
|
On error, don't move point.
|
|
|
|
|
|
|
|
The returned object will be a vector, list, hashtable, alist, or
|
|
|
|
plist. Its elements will be the JSON null value, the JSON false
|
|
|
|
value, t, numbers, strings, or further vectors, lists, hashtables,
|
|
|
|
alists, or plists. If there are duplicate keys in an object, all
|
|
|
|
but the last one are ignored.
|
|
|
|
|
|
|
|
If the current buffer doesn't contain a valid JSON object, the
|
|
|
|
function signals an error of type `json-parse-error'.
|
|
|
|
|
|
|
|
The arguments ARGS are a list of keyword/argument pairs:
|
|
|
|
|
|
|
|
The keyword argument `:object-type' specifies which Lisp type is used
|
|
|
|
to represent objects; it can be `hash-table', `alist' or `plist'. It
|
|
|
|
defaults to `hash-table'.
|
|
|
|
|
|
|
|
The keyword argument `:array-type' specifies which Lisp type is used
|
|
|
|
to represent arrays; it can be `array' (the default) or `list'.
|
|
|
|
|
|
|
|
The keyword argument `:null-object' specifies which object to use
|
|
|
|
to represent a JSON null value. It defaults to `:null'.
|
|
|
|
|
|
|
|
The keyword argument `:false-object' specifies which object to use to
|
|
|
|
represent a JSON false value. It defaults to `:false'.
|
2018-06-08 02:35:50 +01:00
|
|
|
usage: (json-parse-buffer &rest args) */)
|
2018-06-07 17:41:19 +01:00
|
|
|
(ptrdiff_t nargs, Lisp_Object *args)
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
{
|
|
|
|
ptrdiff_t count = SPECPDL_INDEX ();
|
|
|
|
|
2017-12-10 18:36:37 +02:00
|
|
|
#ifdef WINDOWSNT
|
|
|
|
if (!json_initialized)
|
|
|
|
{
|
|
|
|
Lisp_Object status;
|
|
|
|
json_initialized = init_json_functions ();
|
|
|
|
status = json_initialized ? Qt : Qnil;
|
|
|
|
Vlibrary_cache = Fcons (Fcons (Qjson, status), Vlibrary_cache);
|
|
|
|
}
|
|
|
|
if (!json_initialized)
|
|
|
|
{
|
|
|
|
message1 ("jansson library not found");
|
|
|
|
return Qnil;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2019-04-13 01:33:05 +03:00
|
|
|
struct json_configuration conf =
|
|
|
|
{json_object_hashtable, json_array_array, QCnull, QCfalse};
|
2018-06-08 02:35:50 +01:00
|
|
|
json_parse_args (nargs, args, &conf, true);
|
2017-12-13 23:35:07 +01:00
|
|
|
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
ptrdiff_t point = PT_BYTE;
|
|
|
|
struct json_read_buffer_data data = {.point = point};
|
|
|
|
json_error_t error;
|
|
|
|
json_t *object = json_load_callback (json_read_buffer_callback, &data,
|
|
|
|
JSON_DISABLE_EOF_CHECK, &error);
|
|
|
|
|
|
|
|
if (object == NULL)
|
|
|
|
json_parse_error (&error);
|
|
|
|
|
|
|
|
/* Avoid leaking the object in case of further errors. */
|
|
|
|
record_unwind_protect_ptr (json_release_object, object);
|
|
|
|
|
|
|
|
/* Convert and then move point only if everything succeeded. */
|
2018-06-07 17:41:19 +01:00
|
|
|
Lisp_Object lisp = json_to_lisp (object, &conf);
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
|
|
|
|
/* Adjust point by how much we just read. */
|
|
|
|
point += error.position;
|
|
|
|
SET_PT_BOTH (BYTE_TO_CHAR (point), point);
|
|
|
|
|
|
|
|
return unbind_to (count, lisp);
|
|
|
|
}
|
|
|
|
|
2017-12-14 19:53:58 +02:00
|
|
|
/* Simplified version of 'define-error' that works with pure
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
objects. */
|
|
|
|
|
|
|
|
static void
|
|
|
|
define_error (Lisp_Object name, const char *message, Lisp_Object parent)
|
|
|
|
{
|
|
|
|
eassert (SYMBOLP (name));
|
|
|
|
eassert (SYMBOLP (parent));
|
|
|
|
Lisp_Object parent_conditions = Fget (parent, Qerror_conditions);
|
|
|
|
eassert (CONSP (parent_conditions));
|
|
|
|
eassert (!NILP (Fmemq (parent, parent_conditions)));
|
|
|
|
eassert (NILP (Fmemq (name, parent_conditions)));
|
|
|
|
Fput (name, Qerror_conditions, pure_cons (name, parent_conditions));
|
|
|
|
Fput (name, Qerror_message, build_pure_c_string (message));
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
syms_of_json (void)
|
|
|
|
{
|
|
|
|
DEFSYM (QCnull, ":null");
|
|
|
|
DEFSYM (QCfalse, ":false");
|
|
|
|
|
|
|
|
DEFSYM (Qstring_without_embedded_nulls_p, "string-without-embedded-nulls-p");
|
|
|
|
DEFSYM (Qjson_value_p, "json-value-p");
|
2017-12-23 17:56:36 +01:00
|
|
|
DEFSYM (Qutf_8_string_p, "utf-8-string-p");
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
|
|
|
|
DEFSYM (Qjson_error, "json-error");
|
|
|
|
DEFSYM (Qjson_out_of_memory, "json-out-of-memory");
|
|
|
|
DEFSYM (Qjson_parse_error, "json-parse-error");
|
|
|
|
DEFSYM (Qjson_end_of_file, "json-end-of-file");
|
|
|
|
DEFSYM (Qjson_trailing_content, "json-trailing-content");
|
|
|
|
DEFSYM (Qjson_object_too_deep, "json-object-too-deep");
|
|
|
|
define_error (Qjson_error, "generic JSON error", Qerror);
|
|
|
|
define_error (Qjson_out_of_memory,
|
|
|
|
"not enough memory for creating JSON object", Qjson_error);
|
|
|
|
define_error (Qjson_parse_error, "could not parse JSON stream",
|
|
|
|
Qjson_error);
|
|
|
|
define_error (Qjson_end_of_file, "end of JSON stream", Qjson_parse_error);
|
|
|
|
define_error (Qjson_trailing_content, "trailing content after JSON stream",
|
|
|
|
Qjson_parse_error);
|
|
|
|
define_error (Qjson_object_too_deep,
|
|
|
|
"object cyclic or Lisp evaluation too deep", Qjson_error);
|
|
|
|
|
|
|
|
DEFSYM (Qpure, "pure");
|
|
|
|
DEFSYM (Qside_effect_free, "side-effect-free");
|
|
|
|
|
|
|
|
DEFSYM (Qjson_serialize, "json-serialize");
|
|
|
|
DEFSYM (Qjson_parse_string, "json-parse-string");
|
|
|
|
Fput (Qjson_serialize, Qpure, Qt);
|
|
|
|
Fput (Qjson_serialize, Qside_effect_free, Qt);
|
|
|
|
Fput (Qjson_parse_string, Qpure, Qt);
|
|
|
|
Fput (Qjson_parse_string, Qside_effect_free, Qt);
|
|
|
|
|
2017-12-13 23:35:07 +01:00
|
|
|
DEFSYM (QCobject_type, ":object-type");
|
2019-04-13 01:33:05 +03:00
|
|
|
DEFSYM (QCarray_type, ":array-type");
|
2018-06-07 17:41:19 +01:00
|
|
|
DEFSYM (QCnull_object, ":null-object");
|
|
|
|
DEFSYM (QCfalse_object, ":false-object");
|
2017-12-13 23:35:07 +01:00
|
|
|
DEFSYM (Qalist, "alist");
|
2018-06-02 00:23:38 +01:00
|
|
|
DEFSYM (Qplist, "plist");
|
2019-04-13 01:33:05 +03:00
|
|
|
DEFSYM (Qarray, "array");
|
2017-12-13 23:35:07 +01:00
|
|
|
|
Implement native JSON support using Jansson
* configure.ac: New option --with-json.
* src/json.c (Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): New defuns.
(json_malloc, json_free, json_has_prefix, json_has_suffix)
(json_make_string, json_build_string, json_encode)
(json_out_of_memory, json_parse_error)
(json_release_object, check_string_without_embedded_nulls, json_check)
(lisp_to_json, lisp_to_json_toplevel, lisp_to_json_toplevel_1)
(json_insert, json_insert_callback, json_to_lisp)
(json_read_buffer_callback, Fjson_parse_buffer, define_error): New
helper functions.
(init_json, syms_of_json): New file.
* src/lisp.h: Declaration for init_json and syms_of_json.
* src/emacs.c (main): Enable JSON functions.
* src/eval.c (internal_catch_all, internal_catch_all_1): New helper
functions to catch all signals.
(syms_of_eval): Add uninterned symbol to signify out of memory.
* src/Makefile.in (JSON_LIBS, JSON_CFLAGS, JSON_OBJ, EMACS_CFLAGS)
(base_obj, LIBES): Compile json.c if --with-json is enabled.
* test/src/json-tests.el (json-serialize/roundtrip)
(json-serialize/object, json-parse-string/object)
(json-parse-string/string, json-serialize/string)
(json-parse-string/incomplete, json-parse-string/trailing)
(json-parse-buffer/incomplete, json-parse-buffer/trailing): New unit
tests.
* doc/lispref/text.texi (Parsing JSON): New manual section.
2017-09-18 10:51:39 +02:00
|
|
|
defsubr (&Sjson_serialize);
|
|
|
|
defsubr (&Sjson_insert);
|
|
|
|
defsubr (&Sjson_parse_string);
|
|
|
|
defsubr (&Sjson_parse_buffer);
|
|
|
|
}
|