aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2017-12-10 18:36:37 +0200
committerEli Zaretskii2017-12-10 18:36:37 +0200
commit2b8a1b76920dbdfc39dab2ec29ab7650bf779275 (patch)
tree2080a70b7238f63578d103dae8331e24840edc1c
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.
-rw-r--r--configure.ac5
-rw-r--r--lisp/term/w32-win.el3
-rw-r--r--nt/INSTALL7
-rw-r--r--nt/INSTALL.W641
-rw-r--r--src/emacs.c2
-rw-r--r--src/json.c181
-rw-r--r--src/w32fns.c1
7 files changed, 198 insertions, 2 deletions
diff --git a/configure.ac b/configure.ac
index caee0159548..562b19afe64 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2881,6 +2881,11 @@ if test "${with_json}" = yes; then
2881 AC_DEFINE(HAVE_JSON, 1, [Define if using Jansson.]) 2881 AC_DEFINE(HAVE_JSON, 1, [Define if using Jansson.])
2882 JSON_OBJ=json.o 2882 JSON_OBJ=json.o
2883 fi 2883 fi
2884
2885 # Windows loads libjansson dynamically
2886 if test "${opsys}" = "mingw32"; then
2887 JSON_LIBS=
2888 fi
2884fi 2889fi
2885 2890
2886AC_SUBST(JSON_LIBS) 2891AC_SUBST(JSON_LIBS)
diff --git a/lisp/term/w32-win.el b/lisp/term/w32-win.el
index 4e0e54ae179..1db90aec984 100644
--- a/lisp/term/w32-win.el
+++ b/lisp/term/w32-win.el
@@ -276,7 +276,8 @@ See the documentation of `create-fontset-from-fontset-spec' for the format.")
276 '(gnutls "libgnutls-28.dll" "libgnutls-26.dll")) 276 '(gnutls "libgnutls-28.dll" "libgnutls-26.dll"))
277 '(libxml2 "libxml2-2.dll" "libxml2.dll") 277 '(libxml2 "libxml2-2.dll" "libxml2.dll")
278 '(zlib "zlib1.dll" "libz-1.dll") 278 '(zlib "zlib1.dll" "libz-1.dll")
279 '(lcms2 "liblcms2-2.dll"))) 279 '(lcms2 "liblcms2-2.dll")
280 '(json "libjansson-4.dll")))
280 281
281;;; multi-tty support 282;;; multi-tty support
282(defvar w32-initialized nil 283(defvar w32-initialized nil
diff --git a/nt/INSTALL b/nt/INSTALL
index 30e14293f5c..361d607ff68 100644
--- a/nt/INSTALL
+++ b/nt/INSTALL
@@ -806,6 +806,13 @@ build will run on Windows 9X and newer systems).
806 Prebuilt binaries of lcms2 DLL (for 32-bit builds of Emacs) are 806 Prebuilt binaries of lcms2 DLL (for 32-bit builds of Emacs) are
807 available from the ezwinports site and from the MSYS2 project. 807 available from the ezwinports site and from the MSYS2 project.
808 808
809* Optional support for JSON
810
811 Emacs can provide built-in support for JSON parsing and
812 serialization using the libjansson library. Prebuilt binaries of
813 the libjansson DLL (for 32-bit builds of Emacs) are available from
814 the ezwinports site and from the MSYS2 project.
815
809 816
810This file is part of GNU Emacs. 817This file is part of GNU Emacs.
811 818
diff --git a/nt/INSTALL.W64 b/nt/INSTALL.W64
index e08b72f2ca0..41d57bd3689 100644
--- a/nt/INSTALL.W64
+++ b/nt/INSTALL.W64
@@ -52,6 +52,7 @@ packages (you can copy and paste it into the shell with Shift + Insert):
52 mingw-w64-x86_64-libjpeg-turbo \ 52 mingw-w64-x86_64-libjpeg-turbo \
53 mingw-w64-x86_64-librsvg \ 53 mingw-w64-x86_64-librsvg \
54 mingw-w64-x86_64-lcms2 \ 54 mingw-w64-x86_64-lcms2 \
55 mingw-w64-x86_64-jansson \
55 mingw-w64-x86_64-libxml2 \ 56 mingw-w64-x86_64-libxml2 \
56 mingw-w64-x86_64-gnutls \ 57 mingw-w64-x86_64-gnutls \
57 mingw-w64-x86_64-zlib 58 mingw-w64-x86_64-zlib
diff --git a/src/emacs.c b/src/emacs.c
index 7c1ae1f2c5b..5a6b896ef47 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -1262,7 +1262,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1262 running_asynch_code = 0; 1262 running_asynch_code = 0;
1263 init_random (); 1263 init_random ();
1264 1264
1265#ifdef HAVE_JSON 1265#if defined HAVE_JSON && !defined WINDOWSNT
1266 init_json (); 1266 init_json ();
1267#endif 1267#endif
1268 1268
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;
diff --git a/src/w32fns.c b/src/w32fns.c
index d2d4b2c7355..90d09542c45 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -10418,6 +10418,7 @@ syms_of_w32fns (void)
10418 DEFSYM (Qserif, "serif"); 10418 DEFSYM (Qserif, "serif");
10419 DEFSYM (Qzlib, "zlib"); 10419 DEFSYM (Qzlib, "zlib");
10420 DEFSYM (Qlcms2, "lcms2"); 10420 DEFSYM (Qlcms2, "lcms2");
10421 DEFSYM (Qjson, "json");
10421 10422
10422 Fput (Qundefined_color, Qerror_conditions, 10423 Fput (Qundefined_color, Qerror_conditions,
10423 listn (CONSTYPE_PURE, 2, Qundefined_color, Qerror)); 10424 listn (CONSTYPE_PURE, 2, Qundefined_color, Qerror));