aboutsummaryrefslogtreecommitdiffstats
path: root/src/json.c
diff options
context:
space:
mode:
authorEli Zaretskii2017-12-10 18:36:37 +0200
committerEli Zaretskii2017-12-10 18:36:37 +0200
commit2b8a1b76920dbdfc39dab2ec29ab7650bf779275 (patch)
tree2080a70b7238f63578d103dae8331e24840edc1c /src/json.c
parentf856d1e4489eac45afab865838abb2b16fb1f14f (diff)
downloademacs-2b8a1b76920dbdfc39dab2ec29ab7650bf779275.tar.gz
emacs-2b8a1b76920dbdfc39dab2ec29ab7650bf779275.zip
Support dynamic loading of libjansson on MS-Windows
* src/json.c [WINDOWSNT]: Define fn_* function pointers to jansson functions. (json_delete) [WINDOWSNT]: A wrapper around fn_json_delete, needed by json_decref. (init_json_functions) [WINDOWSNT]: New function. (Fjson_serialize, Fjson_insert, Fjson_parse_string) (Fjson_parse_buffer) [WINDOWSNT]: Call init_json_functions if needed, and record JSON in Vlibrary_cache. * src/emacs.c (main): Don't call init_json on WINDOWSNT. * src/w32fns.c (syms_of_w32fns): DEFSYM "json". * lisp/term/w32-win.el (dynamic-library-alist): Add JSON DLL to the list. * configure.ac (HAVE_JSON): Empty JSON_LIBS for MinGW. * nt/INSTALL.W64: * nt/INSTALL: Add information about libjansson.
Diffstat (limited to 'src/json.c')
-rw-r--r--src/json.c181
1 files changed, 181 insertions, 0 deletions
diff --git a/src/json.c b/src/json.c
index dc449e43e11..7025ae165cd 100644
--- a/src/json.c
+++ b/src/json.c
@@ -30,6 +30,126 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
30#include "buffer.h" 30#include "buffer.h"
31#include "coding.h" 31#include "coding.h"
32 32
33#ifdef WINDOWSNT
34# include <windows.h>
35# include "w32.h"
36
37DEF_DLL_FN (void, json_set_alloc_funcs,
38 (json_malloc_t malloc_fn, json_free_t free_fn));
39DEF_DLL_FN (void, json_delete, (json_t *json));
40DEF_DLL_FN (json_t *, json_array, (void));
41DEF_DLL_FN (int, json_array_append_new, (json_t *array, json_t *value));
42DEF_DLL_FN (size_t, json_array_size, (const json_t *array));
43DEF_DLL_FN (json_t *, json_object, (void));
44DEF_DLL_FN (int, json_object_set_new,
45 (json_t *object, const char *key, json_t *value));
46DEF_DLL_FN (json_t *, json_null, (void));
47DEF_DLL_FN (json_t *, json_true, (void));
48DEF_DLL_FN (json_t *, json_false, (void));
49DEF_DLL_FN (json_t *, json_integer, (json_int_t value));
50DEF_DLL_FN (json_t *, json_real, (double value));
51DEF_DLL_FN (json_t *, json_stringn, (const char *value, size_t len));
52DEF_DLL_FN (char *, json_dumps, (const json_t *json, size_t flags));
53DEF_DLL_FN (int, json_dump_callback,
54 (const json_t *json, json_dump_callback_t callback, void *data,
55 size_t flags));
56DEF_DLL_FN (json_int_t, json_integer_value, (const json_t *integer));
57DEF_DLL_FN (double, json_real_value, (const json_t *real));
58DEF_DLL_FN (const char *, json_string_value, (const json_t *string));
59DEF_DLL_FN (size_t, json_string_length, (const json_t *string));
60DEF_DLL_FN (json_t *, json_array_get, (const json_t *array, size_t index));
61DEF_DLL_FN (size_t, json_object_size, (const json_t *object));
62DEF_DLL_FN (const char *, json_object_iter_key, (void *iter));
63DEF_DLL_FN (void *, json_object_iter, (json_t *object));
64DEF_DLL_FN (json_t *, json_object_iter_value, (void *iter));
65DEF_DLL_FN (void *, json_object_key_to_iter, (const char *key));
66DEF_DLL_FN (void *, json_object_iter_next, (json_t *object, void *iter));
67DEF_DLL_FN (json_t *, json_loads,
68 (const char *input, size_t flags, json_error_t *error));
69DEF_DLL_FN (json_t *, json_load_callback,
70 (json_load_callback_t callback, void *data, size_t flags,
71 json_error_t *error));
72
73/* This is called by json_decref, which is an inline function. */
74void json_delete(json_t *json)
75{
76 fn_json_delete (json);
77}
78
79static bool json_initialized;
80
81static bool
82init_json_functions (void)
83{
84 HMODULE library = w32_delayed_load (Qjson);
85
86 if (!library)
87 return false;
88
89 LOAD_DLL_FN (library, json_set_alloc_funcs);
90 LOAD_DLL_FN (library, json_delete);
91 LOAD_DLL_FN (library, json_array);
92 LOAD_DLL_FN (library, json_array_append_new);
93 LOAD_DLL_FN (library, json_array_size);
94 LOAD_DLL_FN (library, json_object);
95 LOAD_DLL_FN (library, json_object_set_new);
96 LOAD_DLL_FN (library, json_null);
97 LOAD_DLL_FN (library, json_true);
98 LOAD_DLL_FN (library, json_false);
99 LOAD_DLL_FN (library, json_integer);
100 LOAD_DLL_FN (library, json_real);
101 LOAD_DLL_FN (library, json_stringn);
102 LOAD_DLL_FN (library, json_dumps);
103 LOAD_DLL_FN (library, json_dump_callback);
104 LOAD_DLL_FN (library, json_integer_value);
105 LOAD_DLL_FN (library, json_real_value);
106 LOAD_DLL_FN (library, json_string_value);
107 LOAD_DLL_FN (library, json_string_length);
108 LOAD_DLL_FN (library, json_array_get);
109 LOAD_DLL_FN (library, json_object_size);
110 LOAD_DLL_FN (library, json_object_iter_key);
111 LOAD_DLL_FN (library, json_object_iter);
112 LOAD_DLL_FN (library, json_object_iter_value);
113 LOAD_DLL_FN (library, json_object_key_to_iter);
114 LOAD_DLL_FN (library, json_object_iter_next);
115 LOAD_DLL_FN (library, json_loads);
116 LOAD_DLL_FN (library, json_load_callback);
117
118 init_json ();
119
120 return true;
121}
122
123#define json_set_alloc_funcs fn_json_set_alloc_funcs
124#define json_array fn_json_array
125#define json_array_append_new fn_json_array_append_new
126#define json_array_size fn_json_array_size
127#define json_object fn_json_object
128#define json_object_set_new fn_json_object_set_new
129#define json_null fn_json_null
130#define json_true fn_json_true
131#define json_false fn_json_false
132#define json_integer fn_json_integer
133#define json_real fn_json_real
134#define json_stringn fn_json_stringn
135#define json_dumps fn_json_dumps
136#define json_dump_callback fn_json_dump_callback
137#define json_integer_value fn_json_integer_value
138#define json_real_value fn_json_real_value
139#define json_string_value fn_json_string_value
140#define json_string_length fn_json_string_length
141#define json_array_get fn_json_array_get
142#define json_object_size fn_json_object_size
143#define json_object_iter_key fn_json_object_iter_key
144#define json_object_iter fn_json_object_iter
145#define json_object_iter_value fn_json_object_iter_value
146#define json_object_key_to_iter fn_json_object_key_to_iter
147#define json_object_iter_next fn_json_object_iter_next
148#define json_loads fn_json_loads
149#define json_load_callback fn_json_load_callback
150
151#endif /* WINDOWSNT */
152
33/* We install a custom allocator so that we can avoid objects larger 153/* We install a custom allocator so that we can avoid objects larger
34 than PTRDIFF_MAX. Such objects wouldn’t play well with the rest of 154 than PTRDIFF_MAX. Such objects wouldn’t play well with the rest of
35 Emacs’s codebase, which generally uses ptrdiff_t for sizes and 155 Emacs’s codebase, which generally uses ptrdiff_t for sizes and
@@ -277,6 +397,21 @@ each object. */)
277{ 397{
278 ptrdiff_t count = SPECPDL_INDEX (); 398 ptrdiff_t count = SPECPDL_INDEX ();
279 399
400#ifdef WINDOWSNT
401 if (!json_initialized)
402 {
403 Lisp_Object status;
404 json_initialized = init_json_functions ();
405 status = json_initialized ? Qt : Qnil;
406 Vlibrary_cache = Fcons (Fcons (Qjson, status), Vlibrary_cache);
407 }
408 if (!json_initialized)
409 {
410 message1 ("jansson library not found");
411 return Qnil;
412 }
413#endif
414
280 json_t *json = lisp_to_json_toplevel (object); 415 json_t *json = lisp_to_json_toplevel (object);
281 record_unwind_protect_ptr (json_release_object, json); 416 record_unwind_protect_ptr (json_release_object, json);
282 417
@@ -340,6 +475,21 @@ OBJECT. */)
340{ 475{
341 ptrdiff_t count = SPECPDL_INDEX (); 476 ptrdiff_t count = SPECPDL_INDEX ();
342 477
478#ifdef WINDOWSNT
479 if (!json_initialized)
480 {
481 Lisp_Object status;
482 json_initialized = init_json_functions ();
483 status = json_initialized ? Qt : Qnil;
484 Vlibrary_cache = Fcons (Fcons (Qjson, status), Vlibrary_cache);
485 }
486 if (!json_initialized)
487 {
488 message1 ("jansson library not found");
489 return Qnil;
490 }
491#endif
492
343 json_t *json = lisp_to_json (object); 493 json_t *json = lisp_to_json (object);
344 record_unwind_protect_ptr (json_release_object, json); 494 record_unwind_protect_ptr (json_release_object, json);
345 495
@@ -439,6 +589,22 @@ an error of type `json-parse-error' is signaled. */)
439 (Lisp_Object string) 589 (Lisp_Object string)
440{ 590{
441 ptrdiff_t count = SPECPDL_INDEX (); 591 ptrdiff_t count = SPECPDL_INDEX ();
592
593#ifdef WINDOWSNT
594 if (!json_initialized)
595 {
596 Lisp_Object status;
597 json_initialized = init_json_functions ();
598 status = json_initialized ? Qt : Qnil;
599 Vlibrary_cache = Fcons (Fcons (Qjson, status), Vlibrary_cache);
600 }
601 if (!json_initialized)
602 {
603 message1 ("jansson library not found");
604 return Qnil;
605 }
606#endif
607
442 Lisp_Object encoded = json_encode (string); 608 Lisp_Object encoded = json_encode (string);
443 check_string_without_embedded_nulls (encoded); 609 check_string_without_embedded_nulls (encoded);
444 610
@@ -493,6 +659,21 @@ not moved. */)
493{ 659{
494 ptrdiff_t count = SPECPDL_INDEX (); 660 ptrdiff_t count = SPECPDL_INDEX ();
495 661
662#ifdef WINDOWSNT
663 if (!json_initialized)
664 {
665 Lisp_Object status;
666 json_initialized = init_json_functions ();
667 status = json_initialized ? Qt : Qnil;
668 Vlibrary_cache = Fcons (Fcons (Qjson, status), Vlibrary_cache);
669 }
670 if (!json_initialized)
671 {
672 message1 ("jansson library not found");
673 return Qnil;
674 }
675#endif
676
496 ptrdiff_t point = PT_BYTE; 677 ptrdiff_t point = PT_BYTE;
497 struct json_read_buffer_data data = {.point = point}; 678 struct json_read_buffer_data data = {.point = point};
498 json_error_t error; 679 json_error_t error;