emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master 2b8a1b7: Support dynamic loading of libjansson on M


From: Eli Zaretskii
Subject: [Emacs-diffs] master 2b8a1b7: Support dynamic loading of libjansson on MS-Windows
Date: Sun, 10 Dec 2017 11:38:05 -0500 (EST)

branch: master
commit 2b8a1b76920dbdfc39dab2ec29ab7650bf779275
Author: Eli Zaretskii <address@hidden>
Commit: Eli Zaretskii <address@hidden>

    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.
---
 configure.ac         |   5 ++
 lisp/term/w32-win.el |   3 +-
 nt/INSTALL           |   7 ++
 nt/INSTALL.W64       |   1 +
 src/emacs.c          |   2 +-
 src/json.c           | 181 +++++++++++++++++++++++++++++++++++++++++++++++++++
 src/w32fns.c         |   1 +
 7 files changed, 198 insertions(+), 2 deletions(-)

diff --git a/configure.ac b/configure.ac
index caee015..562b19a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2881,6 +2881,11 @@ if test "${with_json}" = yes; then
     AC_DEFINE(HAVE_JSON, 1, [Define if using Jansson.])
     JSON_OBJ=json.o
   fi
+
+  # Windows loads libjansson dynamically
+  if test "${opsys}" = "mingw32"; then
+    JSON_LIBS=
+  fi
 fi
 
 AC_SUBST(JSON_LIBS)
diff --git a/lisp/term/w32-win.el b/lisp/term/w32-win.el
index 4e0e54a..1db90ae 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.")
         '(gnutls "libgnutls-28.dll" "libgnutls-26.dll"))
        '(libxml2 "libxml2-2.dll" "libxml2.dll")
        '(zlib "zlib1.dll" "libz-1.dll")
-       '(lcms2 "liblcms2-2.dll")))
+       '(lcms2 "liblcms2-2.dll")
+       '(json "libjansson-4.dll")))
 
 ;;; multi-tty support
 (defvar w32-initialized nil
diff --git a/nt/INSTALL b/nt/INSTALL
index 30e1429..361d607 100644
--- a/nt/INSTALL
+++ b/nt/INSTALL
@@ -806,6 +806,13 @@ build will run on Windows 9X and newer systems).
   Prebuilt binaries of lcms2 DLL (for 32-bit builds of Emacs) are
   available from the ezwinports site and from the MSYS2 project.
 
+* Optional support for JSON
+
+  Emacs can provide built-in support for JSON parsing and
+  serialization using the libjansson library.  Prebuilt binaries of
+  the libjansson DLL (for 32-bit builds of Emacs) are available from
+  the ezwinports site and from the MSYS2 project.
+
 
 This file is part of GNU Emacs.
 
diff --git a/nt/INSTALL.W64 b/nt/INSTALL.W64
index e08b72f..41d57bd 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):
   mingw-w64-x86_64-libjpeg-turbo \
   mingw-w64-x86_64-librsvg \
   mingw-w64-x86_64-lcms2 \
+  mingw-w64-x86_64-jansson \
   mingw-w64-x86_64-libxml2 \
   mingw-w64-x86_64-gnutls \
   mingw-w64-x86_64-zlib
diff --git a/src/emacs.c b/src/emacs.c
index 7c1ae1f..5a6b896 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
   running_asynch_code = 0;
   init_random ();
 
-#ifdef HAVE_JSON
+#if defined HAVE_JSON && !defined WINDOWSNT
   init_json ();
 #endif
 
diff --git a/src/json.c b/src/json.c
index dc449e4..7025ae1 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/>.  */
 #include "buffer.h"
 #include "coding.h"
 
+#ifdef WINDOWSNT
+# include <windows.h>
+# 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));
+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);
+  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
+#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 */
+
 /* We install a custom allocator so that we can avoid objects larger
    than PTRDIFF_MAX.  Such objects wouldn’t play well with the rest of
    Emacs’s codebase, which generally uses ptrdiff_t for sizes and
@@ -277,6 +397,21 @@ each object.  */)
 {
   ptrdiff_t count = SPECPDL_INDEX ();
 
+#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
+
   json_t *json = lisp_to_json_toplevel (object);
   record_unwind_protect_ptr (json_release_object, json);
 
@@ -340,6 +475,21 @@ OBJECT.  */)
 {
   ptrdiff_t count = SPECPDL_INDEX ();
 
+#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
+
   json_t *json = lisp_to_json (object);
   record_unwind_protect_ptr (json_release_object, json);
 
@@ -439,6 +589,22 @@ an error of type `json-parse-error' is signaled.  */)
   (Lisp_Object string)
 {
   ptrdiff_t count = SPECPDL_INDEX ();
+
+#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
+
   Lisp_Object encoded = json_encode (string);
   check_string_without_embedded_nulls (encoded);
 
@@ -493,6 +659,21 @@ not moved.  */)
 {
   ptrdiff_t count = SPECPDL_INDEX ();
 
+#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
+
   ptrdiff_t point = PT_BYTE;
   struct json_read_buffer_data data = {.point = point};
   json_error_t error;
diff --git a/src/w32fns.c b/src/w32fns.c
index d2d4b2c..90d0954 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -10418,6 +10418,7 @@ syms_of_w32fns (void)
   DEFSYM (Qserif, "serif");
   DEFSYM (Qzlib, "zlib");
   DEFSYM (Qlcms2, "lcms2");
+  DEFSYM (Qjson, "json");
 
   Fput (Qundefined_color, Qerror_conditions,
        listn (CONSTYPE_PURE, 2, Qundefined_color, Qerror));



reply via email to

[Prev in Thread] Current Thread [Next in Thread]