emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] scratch/support-plists-in-jsonc 506d384: Instead of a json


From: João Távora
Subject: [Emacs-diffs] scratch/support-plists-in-jsonc 506d384: Instead of a json-serialize-use-plists global, use function args
Date: Tue, 29 May 2018 21:54:52 -0400 (EDT)

branch: scratch/support-plists-in-jsonc
commit 506d38434b54a3999163a78c91fb06a524a5cad2
Author: João Távora <address@hidden>
Commit: João Távora <address@hidden>

    Instead of a json-serialize-use-plists global, use function args
    
    * src/json.c (syms_of_json): Don't defive
    json-serialize-use-plists
    (Fjson_insert, lisp_to_json, list_to_json_toplevel_1)
    (list_to_json_toplevel, Fjson_serialize): Use and pass around
    use_plists arg.
    
    * doc/lispref/text.texi:
    (Parsing JSON): json-serialize and json-insert now have a
    USE-PLISTS arg.
    
    * test/src/json-tests.el (json-serialize/object): Use
    json-serialize's USE-PLISTS arg.
---
 doc/lispref/text.texi  | 15 +++++-------
 src/json.c             | 66 +++++++++++++++++++++++++-------------------------
 test/src/json-tests.el | 21 ++++++++--------
 3 files changed, 49 insertions(+), 53 deletions(-)

diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi
index 3995102..d2371d6 100644
--- a/doc/lispref/text.texi
+++ b/doc/lispref/text.texi
@@ -5067,22 +5067,19 @@ either @code{hash-table} to parse JSON objects as 
hashtables with
 string keys (the default), @code{alist} to parse them as alists or
 @code{plist} to parse them as plists.
 
address@hidden json-serialize-use-plists
 @cindex serializing plists as json
-  For the serialization function, the variable
address@hidden controls the converse process,
-resolving the ambiguity when a list is found in the Lisp object to
-serialize. If @code{nil}, its default, the list is interpreted as an
-alist, otherwise it is interpreted as a plist.
-
 @defun json-serialize object
 This function returns a new Lisp string which contains the JSON
-representation of @var{object}.
+representation of @var{object}. The optional argument @var{use-plists}
+resolves the ambiguity when a list is found in the Lisp object to
+serialize: if it is @code{nil}, its default, the list is interpreted
+as an alist, otherwise it is interpreted as a plist.
 @end defun
 
 @defun json-insert object
 This function inserts the JSON representation of @var{object} into the
-current buffer before point.
+current buffer before point. The optional argument @var{use-plists} is
+interpreted as in @dfn{json-serialize}.
 @end defun
 
 @defun json-parse-string string &key (object-type @code{hash-table})
diff --git a/src/json.c b/src/json.c
index ccd58c0..8318b63 100644
--- a/src/json.c
+++ b/src/json.c
@@ -325,14 +325,14 @@ json_check_utf8 (Lisp_Object string)
   CHECK_TYPE (utf8_string_p (string), Qutf_8_string_p, string);
 }
 
-static json_t *lisp_to_json (Lisp_Object);
+static json_t *lisp_to_json (Lisp_Object, Lisp_Object);
 
 /* Convert a Lisp object to a toplevel JSON object (array or object).
    This returns Lisp_Object so we can use unbind_to.  The return value
    is always nil.  */
 
 static _GL_ARG_NONNULL ((2)) Lisp_Object
-lisp_to_json_toplevel_1 (Lisp_Object lisp, json_t **json)
+lisp_to_json_toplevel_1 (Lisp_Object lisp, Lisp_Object use_plists, json_t 
**json)
 {
   if (VECTORP (lisp))
     {
@@ -343,7 +343,8 @@ lisp_to_json_toplevel_1 (Lisp_Object lisp, json_t **json)
       for (ptrdiff_t i = 0; i < size; ++i)
         {
           int status
-            = json_array_append_new (*json, lisp_to_json (AREF (lisp, i)));
+            = json_array_append_new (*json, lisp_to_json (AREF (lisp, i),
+                                                          use_plists));
           if (status == -1)
             json_out_of_memory ();
         }
@@ -370,7 +371,8 @@ lisp_to_json_toplevel_1 (Lisp_Object lisp, json_t **json)
             if (json_object_get (*json, key_str) != NULL)
               wrong_type_argument (Qjson_value_p, lisp);
             int status = json_object_set_new (*json, key_str,
-                                              lisp_to_json (HASH_VALUE (h, 
i)));
+                                              lisp_to_json (HASH_VALUE (h, i),
+                                                            use_plists));
             if (status == -1)
               {
                 /* A failure can be caused either by an invalid key or
@@ -398,7 +400,7 @@ lisp_to_json_toplevel_1 (Lisp_Object lisp, json_t **json)
           const char *key_str;
           Lisp_Object value;
           Lisp_Object key_symbol;
-          if ( EQ (Vjson_serialize_use_plists, Qt) ) {
+          if ( EQ (use_plists, Qt) ) {
             key_symbol = XCAR (tail);
             tail = XCDR(tail);
             CHECK_CONS (tail);
@@ -417,14 +419,15 @@ lisp_to_json_toplevel_1 (Lisp_Object lisp, json_t **json)
           check_string_without_embedded_nulls (key);
           key_str = SSDATA (key);
           /* If using plists, maybe strip the ":" from symbol-name */
-          if (EQ (Vjson_serialize_use_plists, Qt) &&
+          if (EQ (use_plists, Qt) &&
               ':' == key_str[0] &&
               key_str[1] ) key_str = &key_str[1];
           /* Only add element if key is not already present.  */
           if (json_object_get (*json, key_str) == NULL)
             {
               int status
-                = json_object_set_new (*json, key_str, lisp_to_json (value));
+                = json_object_set_new (*json, key_str,
+                                       lisp_to_json (value, use_plists));
               if (status == -1)
                 json_out_of_memory ();
             }
@@ -441,12 +444,12 @@ lisp_to_json_toplevel_1 (Lisp_Object lisp, json_t **json)
    hashtable, or alist.  */
 
 static json_t *
-lisp_to_json_toplevel (Lisp_Object lisp)
+lisp_to_json_toplevel (Lisp_Object lisp, Lisp_Object use_plists)
 {
   if (++lisp_eval_depth > max_lisp_eval_depth)
     xsignal0 (Qjson_object_too_deep);
   json_t *json;
-  lisp_to_json_toplevel_1 (lisp, &json);
+  lisp_to_json_toplevel_1 (lisp, use_plists, &json);
   --lisp_eval_depth;
   return json;
 }
@@ -456,7 +459,7 @@ lisp_to_json_toplevel (Lisp_Object lisp)
    JSON object.  */
 
 static json_t *
-lisp_to_json (Lisp_Object lisp)
+lisp_to_json (Lisp_Object lisp, Lisp_Object use_plists)
 {
   if (EQ (lisp, QCnull))
     return json_check (json_null ());
@@ -486,24 +489,26 @@ lisp_to_json (Lisp_Object lisp)
     }
 
   /* LISP now must be a vector, hashtable, or alist.  */
-  return lisp_to_json_toplevel (lisp);
+  return lisp_to_json_toplevel (lisp, use_plists);
 }
 
-DEFUN ("json-serialize", Fjson_serialize, Sjson_serialize, 1, 1, NULL,
+DEFUN ("json-serialize", Fjson_serialize, Sjson_serialize, 1, 2, NULL,
        doc: /* Return the JSON representation of OBJECT as a string.
 
 OBJECT must be a vector of values or a key-value map.  Hashtables,
-alists and plists are accepted as maps, the variable
-`json-serialize-use-plists' controlling which one of the latter two to
-use.  In any of these cases, values can be `:null', `:false', t,
-numbers, strings, or, recursively, other vectors, hashtables, alists
-or plists.  `:null', `:false', and t will be converted to JSON null,
-false, and true values, respectively.  Vectors will be converted to
-JSON arrays, and hashtables, alists and plists to JSON objects.
-Hashtable keys must be strings without embedded null characters and
-must be unique within each object.  Alist or plist keys must be
-symbols; if a key is duplicate, the first instance is used.  */)
-  (Lisp_Object object)
+alists and plists are accepted as maps.  Since the latter two are both
+lists and this function can't currently guess the format from the
+variable, the optional argument USE-PLISTS is used to control which of
+the two to use.  In any of these cases, values can be `:null',
+`:false', t, numbers, strings, or, recursively, other vectors,
+hashtables, alists or plists.  `:null', `:false', and t will be
+converted to JSON null, false, and true values, respectively.  Vectors
+will be converted to JSON arrays, and hashtables, alists and plists to
+JSON objects.  Hashtable keys must be strings without embedded null
+characters and must be unique within each object.  Alist or plist keys
+must be symbols; if a key is duplicate, the first instance is
+used.  */)
+     (Lisp_Object object, Lisp_Object use_plists)
 {
   ptrdiff_t count = SPECPDL_INDEX ();
 
@@ -522,7 +527,7 @@ symbols; if a key is duplicate, the first instance is used. 
 */)
     }
 #endif
 
-  json_t *json = lisp_to_json_toplevel (object);
+  json_t *json = lisp_to_json_toplevel (object, use_plists);
   record_unwind_protect_ptr (json_release_object, json);
 
   /* If desired, we might want to add the following flags:
@@ -578,12 +583,12 @@ json_insert_callback (const char *buffer, size_t size, 
void *data)
   return NILP (d->error) ? 0 : -1;
 }
 
-DEFUN ("json-insert", Fjson_insert, Sjson_insert, 1, 1, NULL,
+DEFUN ("json-insert", Fjson_insert, Sjson_insert, 1, 2, NULL,
        doc: /* Insert the JSON representation of OBJECT before point.
 This is the same as (insert (json-serialize OBJECT)), but potentially
 faster.  See the function `json-serialize' for allowed values of
-OBJECT.  */)
-  (Lisp_Object object)
+OBJECT and the meaning of USE-PLISTS  */)
+     (Lisp_Object object, Lisp_Object use_plists)
 {
   ptrdiff_t count = SPECPDL_INDEX ();
 
@@ -602,7 +607,7 @@ OBJECT.  */)
     }
 #endif
 
-  json_t *json = lisp_to_json (object);
+  json_t *json = lisp_to_json (object, use_plists);
   record_unwind_protect_ptr (json_release_object, json);
 
   struct json_insert_data data;
@@ -950,11 +955,6 @@ syms_of_json (void)
   DEFSYM (Qpure, "pure");
   DEFSYM (Qside_effect_free, "side-effect-free");
 
-  DEFVAR_LISP ("json-serialize-use-plists", Vjson_serialize_use_plists,
-               doc:
-               /* If non-nil use plists instead of alists in 
json-serialize.*/);
-  Vjson_serialize_use_plists = Qnil;
-
   DEFSYM (Qjson_serialize, "json-serialize");
   DEFSYM (Qjson_parse_string, "json-parse-string");
   Fput (Qjson_serialize, Qpure, Qt);
diff --git a/test/src/json-tests.el b/test/src/json-tests.el
index 5c9be20..b7c17a4 100644
--- a/test/src/json-tests.el
+++ b/test/src/json-tests.el
@@ -71,17 +71,16 @@
   (should-error (json-serialize '#1=((a . 1) . #1#)) :type 'circular-list)
   (should-error (json-serialize '(#1=(a #1#))))
 
-  (let ((json-serialize-use-plists t))
-    (should (equal (json-serialize '(:abc [1 2 t] :def :null))
-                   "{\"abc\":[1,2,true],\"def\":null}"))
-    (should (equal (json-serialize '(abc [1 2 t] :def :null))
-                   "{\"abc\":[1,2,true],\"def\":null}"))
-    (should-error (json-serialize '#1=(:a 1 . #1#)) :type 'circular-list)
-    (should-error (json-serialize '((abc . 1))) :type 'wrong-type-argument)
-    (should-error (json-serialize '(:foo bar (abc . 1)))
-                  :type 'wrong-type-argument)
-    (should-error (json-serialize '(:foo bar :odd-numbered))
-                  :type 'wrong-type-argument)))
+  (should (equal (json-serialize '(:abc [1 2 t] :def :null) t)
+                 "{\"abc\":[1,2,true],\"def\":null}"))
+  (should (equal (json-serialize '(abc [1 2 t] :def :null) t)
+                 "{\"abc\":[1,2,true],\"def\":null}"))
+  (should-error (json-serialize '#1=(:a 1 . #1#) t) :type 'circular-list)
+  (should-error (json-serialize '((abc . 1)) t) :type 'wrong-type-argument)
+  (should-error (json-serialize '(:foo bar (abc . 1)) t)
+                :type 'wrong-type-argument)
+  (should-error (json-serialize '(:foo bar :odd-numbered) t)
+                :type 'wrong-type-argument))
 
 (ert-deftest json-serialize/object-with-duplicate-keys ()
   (skip-unless (fboundp 'json-serialize))



reply via email to

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