]> git.eshelyaron.com Git - emacs.git/commitdiff
Instead of a json-serialize-use-plists global, use function args scratch/support-plists-in-jsonc
authorJoão Távora <joaotavora@gmail.com>
Wed, 30 May 2018 01:48:31 +0000 (02:48 +0100)
committerJoão Távora <joaotavora@gmail.com>
Wed, 30 May 2018 01:53:19 +0000 (02:53 +0100)
* 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
src/json.c
test/src/json-tests.el

index 3995102237a2127cd4f16b8bb0ed4c79b79edd95..d2371d61811d066eb75c8c720a3bbdc33534f563 100644 (file)
@@ -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.
 
-@vindex json-serialize-use-plists
 @cindex serializing plists as json
-  For the serialization function, the variable
-@var{json-serialize-use-plists} 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})
index ccd58c047e5a36b32471b038c171f198bade25c7..8318b637e05b8cb2104426f0eea92902758deda4 100644 (file)
@@ -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);
index 5c9be20e9574edb43ed814cb58d946750f13c3bd..b7c17a4cf1068dd439656114bb5c1319d4c0d5d8 100644 (file)
   (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))