diff options
Diffstat (limited to 'src/json.c')
| -rw-r--r-- | src/json.c | 86 |
1 files changed, 45 insertions, 41 deletions
diff --git a/src/json.c b/src/json.c index 5970c539f53..82df60b8507 100644 --- a/src/json.c +++ b/src/json.c | |||
| @@ -29,18 +29,21 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 29 | #include "buffer.h" | 29 | #include "buffer.h" |
| 30 | #include "coding.h" | 30 | #include "coding.h" |
| 31 | 31 | ||
| 32 | enum json_object_type { | 32 | enum json_object_type |
| 33 | json_object_hashtable, | 33 | { |
| 34 | json_object_alist, | 34 | json_object_hashtable, |
| 35 | json_object_plist | 35 | json_object_alist, |
| 36 | }; | 36 | json_object_plist, |
| 37 | }; | ||
| 37 | 38 | ||
| 38 | enum json_array_type { | 39 | enum json_array_type |
| 39 | json_array_array, | 40 | { |
| 40 | json_array_list | 41 | json_array_array, |
| 41 | }; | 42 | json_array_list, |
| 43 | }; | ||
| 42 | 44 | ||
| 43 | struct json_configuration { | 45 | struct json_configuration |
| 46 | { | ||
| 44 | enum json_object_type object_type; | 47 | enum json_object_type object_type; |
| 45 | enum json_array_type array_type; | 48 | enum json_array_type array_type; |
| 46 | Lisp_Object null_object; | 49 | Lisp_Object null_object; |
| @@ -48,38 +51,37 @@ struct json_configuration { | |||
| 48 | }; | 51 | }; |
| 49 | 52 | ||
| 50 | static void | 53 | static void |
| 51 | json_parse_args (ptrdiff_t nargs, | 54 | json_parse_args (ptrdiff_t nargs, Lisp_Object *args, |
| 52 | Lisp_Object *args, | 55 | struct json_configuration *conf, |
| 53 | struct json_configuration *conf, | 56 | bool parse_object_types) |
| 54 | bool parse_object_types) | ||
| 55 | { | 57 | { |
| 56 | if ((nargs % 2) != 0) | 58 | if ((nargs % 2) != 0) |
| 57 | wrong_type_argument (Qplistp, Flist (nargs, args)); | 59 | wrong_type_argument (Qplistp, Flist (nargs, args)); |
| 58 | 60 | ||
| 59 | /* Start from the back so keyword values appearing | 61 | /* Start from the back so keyword values appearing first take |
| 60 | first take precedence. */ | 62 | precedence. */ |
| 61 | for (ptrdiff_t i = nargs; i > 0; i -= 2) { | 63 | for (ptrdiff_t i = nargs; i > 0; i -= 2) { |
| 62 | Lisp_Object key = args[i - 2]; | 64 | Lisp_Object key = args[i - 2]; |
| 63 | Lisp_Object value = args[i - 1]; | 65 | Lisp_Object value = args[i - 1]; |
| 64 | if (parse_object_types && EQ (key, QCobject_type)) | 66 | if (parse_object_types && EQ (key, QCobject_type)) |
| 65 | { | 67 | { |
| 66 | if (EQ (value, Qhash_table)) | 68 | if (EQ (value, Qhash_table)) |
| 67 | conf->object_type = json_object_hashtable; | 69 | conf->object_type = json_object_hashtable; |
| 68 | else if (EQ (value, Qalist)) | 70 | else if (EQ (value, Qalist)) |
| 69 | conf->object_type = json_object_alist; | 71 | conf->object_type = json_object_alist; |
| 70 | else if (EQ (value, Qplist)) | 72 | else if (EQ (value, Qplist)) |
| 71 | conf->object_type = json_object_plist; | 73 | conf->object_type = json_object_plist; |
| 72 | else | 74 | else |
| 73 | wrong_choice (list3 (Qhash_table, Qalist, Qplist), value); | 75 | wrong_choice (list3 (Qhash_table, Qalist, Qplist), value); |
| 74 | } | 76 | } |
| 75 | else if (parse_object_types && EQ (key, QCarray_type)) | 77 | else if (parse_object_types && EQ (key, QCarray_type)) |
| 76 | { | 78 | { |
| 77 | if (EQ (value, Qarray)) | 79 | if (EQ (value, Qarray)) |
| 78 | conf->array_type = json_array_array; | 80 | conf->array_type = json_array_array; |
| 79 | else if (EQ (value, Qlist)) | 81 | else if (EQ (value, Qlist)) |
| 80 | conf->array_type = json_array_list; | 82 | conf->array_type = json_array_list; |
| 81 | else | 83 | else |
| 82 | wrong_choice (list2 (Qarray, Qlist), value); | 84 | wrong_choice (list2 (Qarray, Qlist), value); |
| 83 | } | 85 | } |
| 84 | else if (EQ (key, QCnull_object)) | 86 | else if (EQ (key, QCnull_object)) |
| 85 | conf->null_object = value; | 87 | conf->null_object = value; |
| @@ -87,19 +89,20 @@ json_parse_args (ptrdiff_t nargs, | |||
| 87 | conf->false_object = value; | 89 | conf->false_object = value; |
| 88 | else if (parse_object_types) | 90 | else if (parse_object_types) |
| 89 | wrong_choice (list4 (QCobject_type, | 91 | wrong_choice (list4 (QCobject_type, |
| 90 | QCarray_type, | 92 | QCarray_type, |
| 91 | QCnull_object, | 93 | QCnull_object, |
| 92 | QCfalse_object), | 94 | QCfalse_object), |
| 93 | value); | 95 | value); |
| 94 | else | 96 | else |
| 95 | wrong_choice (list2 (QCnull_object, | 97 | wrong_choice (list2 (QCnull_object, |
| 96 | QCfalse_object), | 98 | QCfalse_object), |
| 97 | value); | 99 | value); |
| 98 | } | 100 | } |
| 99 | } | 101 | } |
| 100 | 102 | ||
| 101 | /* JSON encoding context. */ | 103 | /* JSON encoding context. */ |
| 102 | typedef struct { | 104 | typedef struct |
| 105 | { | ||
| 103 | char *buf; | 106 | char *buf; |
| 104 | ptrdiff_t size; /* number of bytes in buf */ | 107 | ptrdiff_t size; /* number of bytes in buf */ |
| 105 | ptrdiff_t capacity; /* allocated size of buf */ | 108 | ptrdiff_t capacity; /* allocated size of buf */ |
| @@ -111,7 +114,8 @@ typedef struct { | |||
| 111 | } json_out_t; | 114 | } json_out_t; |
| 112 | 115 | ||
| 113 | /* Set of symbols. */ | 116 | /* Set of symbols. */ |
| 114 | typedef struct { | 117 | typedef struct |
| 118 | { | ||
| 115 | ptrdiff_t count; /* symbols in table */ | 119 | ptrdiff_t count; /* symbols in table */ |
| 116 | int bits; /* log2(table size) */ | 120 | int bits; /* log2(table size) */ |
| 117 | struct symset_tbl *table; /* heap-allocated table */ | 121 | struct symset_tbl *table; /* heap-allocated table */ |
| @@ -129,7 +133,7 @@ struct symset_tbl | |||
| 129 | static inline ptrdiff_t | 133 | static inline ptrdiff_t |
| 130 | symset_size (int bits) | 134 | symset_size (int bits) |
| 131 | { | 135 | { |
| 132 | return (ptrdiff_t)1 << bits; | 136 | return (ptrdiff_t) 1 << bits; |
| 133 | } | 137 | } |
| 134 | 138 | ||
| 135 | static struct symset_tbl * | 139 | static struct symset_tbl * |
| @@ -615,7 +619,7 @@ In you specify the same value for `:null-object' and `:false-object', | |||
| 615 | a potentially ambiguous situation, the JSON output will not contain | 619 | a potentially ambiguous situation, the JSON output will not contain |
| 616 | any JSON false values. | 620 | any JSON false values. |
| 617 | usage: (json-serialize OBJECT &rest ARGS) */) | 621 | usage: (json-serialize OBJECT &rest ARGS) */) |
| 618 | (ptrdiff_t nargs, Lisp_Object *args) | 622 | (ptrdiff_t nargs, Lisp_Object *args) |
| 619 | { | 623 | { |
| 620 | specpdl_ref count = SPECPDL_INDEX (); | 624 | specpdl_ref count = SPECPDL_INDEX (); |
| 621 | json_out_t jo; | 625 | json_out_t jo; |
| @@ -630,7 +634,7 @@ This is the same as (insert (json-serialize OBJECT)), but potentially | |||
| 630 | faster. See the function `json-serialize' for allowed values of | 634 | faster. See the function `json-serialize' for allowed values of |
| 631 | OBJECT. | 635 | OBJECT. |
| 632 | usage: (json-insert OBJECT &rest ARGS) */) | 636 | usage: (json-insert OBJECT &rest ARGS) */) |
| 633 | (ptrdiff_t nargs, Lisp_Object *args) | 637 | (ptrdiff_t nargs, Lisp_Object *args) |
| 634 | { | 638 | { |
| 635 | specpdl_ref count = SPECPDL_INDEX (); | 639 | specpdl_ref count = SPECPDL_INDEX (); |
| 636 | json_out_t jo; | 640 | json_out_t jo; |