diff options
| author | Dmitry Gutov | 2019-04-13 01:33:05 +0300 |
|---|---|---|
| committer | Dmitry Gutov | 2019-04-13 01:33:42 +0300 |
| commit | b41c1ca10fab4ed94e59aea8ad5eae334c2452bd (patch) | |
| tree | 19e3521522c0924e696bbbae80e90fc466c5a61e /src/json.c | |
| parent | cc80eeb4a43d2079963de3d181002a6a6b56560d (diff) | |
| download | emacs-b41c1ca10fab4ed94e59aea8ad5eae334c2452bd.tar.gz emacs-b41c1ca10fab4ed94e59aea8ad5eae334c2452bd.zip | |
Add :array-type option to json-parse-string
* src/json.c (enum json_array_type): New type.
(struct json_configuration): New field array_type.
(json_parse_args): Rename the last argument. Handle the
:array-type keyword argument (bug#32793).
(Fjson_parse_string): Update the docstring accordingly.
(json_to_lisp): Handle the case of :array-type being `list'. Add
a call to 'rarely_quit' inside the loop.
(syms_of_json): Define new symbols.
(Fjson_serialize, Fjson_insert, Fjson_parse_string)
(Fjson_parse_buffer): Update the config struct initializers.
Diffstat (limited to 'src/json.c')
| -rw-r--r-- | src/json.c | 78 |
1 files changed, 65 insertions, 13 deletions
diff --git a/src/json.c b/src/json.c index 5e1439f881a..eb323b498c7 100644 --- a/src/json.c +++ b/src/json.c | |||
| @@ -337,8 +337,14 @@ enum json_object_type { | |||
| 337 | json_object_plist | 337 | json_object_plist |
| 338 | }; | 338 | }; |
| 339 | 339 | ||
| 340 | enum json_array_type { | ||
| 341 | json_array_array, | ||
| 342 | json_array_list | ||
| 343 | }; | ||
| 344 | |||
| 340 | struct json_configuration { | 345 | struct json_configuration { |
| 341 | enum json_object_type object_type; | 346 | enum json_object_type object_type; |
| 347 | enum json_array_type array_type; | ||
| 342 | Lisp_Object null_object; | 348 | Lisp_Object null_object; |
| 343 | Lisp_Object false_object; | 349 | Lisp_Object false_object; |
| 344 | }; | 350 | }; |
| @@ -521,7 +527,7 @@ static void | |||
| 521 | json_parse_args (ptrdiff_t nargs, | 527 | json_parse_args (ptrdiff_t nargs, |
| 522 | Lisp_Object *args, | 528 | Lisp_Object *args, |
| 523 | struct json_configuration *conf, | 529 | struct json_configuration *conf, |
| 524 | bool configure_object_type) | 530 | bool parse_object_types) |
| 525 | { | 531 | { |
| 526 | if ((nargs % 2) != 0) | 532 | if ((nargs % 2) != 0) |
| 527 | wrong_type_argument (Qplistp, Flist (nargs, args)); | 533 | wrong_type_argument (Qplistp, Flist (nargs, args)); |
| @@ -531,7 +537,7 @@ json_parse_args (ptrdiff_t nargs, | |||
| 531 | for (ptrdiff_t i = nargs; i > 0; i -= 2) { | 537 | for (ptrdiff_t i = nargs; i > 0; i -= 2) { |
| 532 | Lisp_Object key = args[i - 2]; | 538 | Lisp_Object key = args[i - 2]; |
| 533 | Lisp_Object value = args[i - 1]; | 539 | Lisp_Object value = args[i - 1]; |
| 534 | if (configure_object_type && EQ (key, QCobject_type)) | 540 | if (parse_object_types && EQ (key, QCobject_type)) |
| 535 | { | 541 | { |
| 536 | if (EQ (value, Qhash_table)) | 542 | if (EQ (value, Qhash_table)) |
| 537 | conf->object_type = json_object_hashtable; | 543 | conf->object_type = json_object_hashtable; |
| @@ -542,12 +548,22 @@ json_parse_args (ptrdiff_t nargs, | |||
| 542 | else | 548 | else |
| 543 | wrong_choice (list3 (Qhash_table, Qalist, Qplist), value); | 549 | wrong_choice (list3 (Qhash_table, Qalist, Qplist), value); |
| 544 | } | 550 | } |
| 551 | else if (parse_object_types && EQ (key, QCarray_type)) | ||
| 552 | { | ||
| 553 | if (EQ (value, Qarray)) | ||
| 554 | conf->array_type = json_array_array; | ||
| 555 | else if (EQ (value, Qlist)) | ||
| 556 | conf->array_type = json_array_list; | ||
| 557 | else | ||
| 558 | wrong_choice (list2 (Qarray, Qlist), value); | ||
| 559 | } | ||
| 545 | else if (EQ (key, QCnull_object)) | 560 | else if (EQ (key, QCnull_object)) |
| 546 | conf->null_object = value; | 561 | conf->null_object = value; |
| 547 | else if (EQ (key, QCfalse_object)) | 562 | else if (EQ (key, QCfalse_object)) |
| 548 | conf->false_object = value; | 563 | conf->false_object = value; |
| 549 | else if (configure_object_type) | 564 | else if (parse_object_types) |
| 550 | wrong_choice (list3 (QCobject_type, | 565 | wrong_choice (list4 (QCobject_type, |
| 566 | QCarray_type, | ||
| 551 | QCnull_object, | 567 | QCnull_object, |
| 552 | QCfalse_object), | 568 | QCfalse_object), |
| 553 | value); | 569 | value); |
| @@ -604,7 +620,8 @@ usage: (json-serialize OBJECT &rest ARGS) */) | |||
| 604 | } | 620 | } |
| 605 | #endif | 621 | #endif |
| 606 | 622 | ||
| 607 | struct json_configuration conf = {json_object_hashtable, QCnull, QCfalse}; | 623 | struct json_configuration conf = |
| 624 | {json_object_hashtable, json_array_array, QCnull, QCfalse}; | ||
| 608 | json_parse_args (nargs - 1, args + 1, &conf, false); | 625 | json_parse_args (nargs - 1, args + 1, &conf, false); |
| 609 | 626 | ||
| 610 | json_t *json = lisp_to_json_toplevel (args[0], &conf); | 627 | json_t *json = lisp_to_json_toplevel (args[0], &conf); |
| @@ -701,7 +718,8 @@ usage: (json-insert OBJECT &rest ARGS) */) | |||
| 701 | } | 718 | } |
| 702 | #endif | 719 | #endif |
| 703 | 720 | ||
| 704 | struct json_configuration conf = {json_object_hashtable, QCnull, QCfalse}; | 721 | struct json_configuration conf = |
| 722 | {json_object_hashtable, json_array_array, QCnull, QCfalse}; | ||
| 705 | json_parse_args (nargs - 1, args + 1, &conf, false); | 723 | json_parse_args (nargs - 1, args + 1, &conf, false); |
| 706 | 724 | ||
| 707 | json_t *json = lisp_to_json (args[0], &conf); | 725 | json_t *json = lisp_to_json (args[0], &conf); |
| @@ -817,10 +835,35 @@ json_to_lisp (json_t *json, struct json_configuration *conf) | |||
| 817 | size_t size = json_array_size (json); | 835 | size_t size = json_array_size (json); |
| 818 | if (PTRDIFF_MAX < size) | 836 | if (PTRDIFF_MAX < size) |
| 819 | overflow_error (); | 837 | overflow_error (); |
| 820 | Lisp_Object result = make_vector (size, Qunbound); | 838 | Lisp_Object result; |
| 821 | for (ptrdiff_t i = 0; i < size; ++i) | 839 | switch (conf->array_type) |
| 822 | ASET (result, i, | 840 | { |
| 823 | json_to_lisp (json_array_get (json, i), conf)); | 841 | case json_array_array: |
| 842 | { | ||
| 843 | result = make_vector (size, Qunbound); | ||
| 844 | for (ptrdiff_t i = 0; i < size; ++i) | ||
| 845 | { | ||
| 846 | rarely_quit (i); | ||
| 847 | ASET (result, i, | ||
| 848 | json_to_lisp (json_array_get (json, i), conf)); | ||
| 849 | } | ||
| 850 | break; | ||
| 851 | } | ||
| 852 | case json_array_list: | ||
| 853 | { | ||
| 854 | result = Qnil; | ||
| 855 | for (ptrdiff_t i = size - 1; i >= 0; --i) | ||
| 856 | { | ||
| 857 | rarely_quit (i); | ||
| 858 | result = Fcons (json_to_lisp (json_array_get (json, i), conf), | ||
| 859 | result); | ||
| 860 | } | ||
| 861 | break; | ||
| 862 | } | ||
| 863 | default: | ||
| 864 | /* Can't get here. */ | ||
| 865 | emacs_abort (); | ||
| 866 | } | ||
| 824 | --lisp_eval_depth; | 867 | --lisp_eval_depth; |
| 825 | return result; | 868 | return result; |
| 826 | } | 869 | } |
| @@ -916,7 +959,12 @@ error of type `json-parse-error' is signaled. The arguments ARGS are | |||
| 916 | a list of keyword/argument pairs: | 959 | a list of keyword/argument pairs: |
| 917 | 960 | ||
| 918 | The keyword argument `:object-type' specifies which Lisp type is used | 961 | The keyword argument `:object-type' specifies which Lisp type is used |
| 919 | to represent objects; it can be `hash-table', `alist' or `plist'. | 962 | to represent objects; it can be `hash-table', `alist' or `plist'. It |
| 963 | defaults to `hash-table'. | ||
| 964 | |||
| 965 | The keyword argument `:array-type' specifies which Lisp type is used | ||
| 966 | to represent arrays; it can be `array' or `list'. It defaults to | ||
| 967 | `array'. | ||
| 920 | 968 | ||
| 921 | The keyword argument `:null-object' specifies which object to use | 969 | The keyword argument `:null-object' specifies which object to use |
| 922 | to represent a JSON null value. It defaults to `:null'. | 970 | to represent a JSON null value. It defaults to `:null'. |
| @@ -946,7 +994,8 @@ usage: (json-parse-string STRING &rest ARGS) */) | |||
| 946 | Lisp_Object string = args[0]; | 994 | Lisp_Object string = args[0]; |
| 947 | Lisp_Object encoded = json_encode (string); | 995 | Lisp_Object encoded = json_encode (string); |
| 948 | check_string_without_embedded_nuls (encoded); | 996 | check_string_without_embedded_nuls (encoded); |
| 949 | struct json_configuration conf = {json_object_hashtable, QCnull, QCfalse}; | 997 | struct json_configuration conf = |
| 998 | {json_object_hashtable, json_array_array, QCnull, QCfalse}; | ||
| 950 | json_parse_args (nargs - 1, args + 1, &conf, true); | 999 | json_parse_args (nargs - 1, args + 1, &conf, true); |
| 951 | 1000 | ||
| 952 | json_error_t error; | 1001 | json_error_t error; |
| @@ -1016,7 +1065,8 @@ usage: (json-parse-buffer &rest args) */) | |||
| 1016 | } | 1065 | } |
| 1017 | #endif | 1066 | #endif |
| 1018 | 1067 | ||
| 1019 | struct json_configuration conf = {json_object_hashtable, QCnull, QCfalse}; | 1068 | struct json_configuration conf = |
| 1069 | {json_object_hashtable, json_array_array, QCnull, QCfalse}; | ||
| 1020 | json_parse_args (nargs, args, &conf, true); | 1070 | json_parse_args (nargs, args, &conf, true); |
| 1021 | 1071 | ||
| 1022 | ptrdiff_t point = PT_BYTE; | 1072 | ptrdiff_t point = PT_BYTE; |
| @@ -1095,10 +1145,12 @@ syms_of_json (void) | |||
| 1095 | Fput (Qjson_parse_string, Qside_effect_free, Qt); | 1145 | Fput (Qjson_parse_string, Qside_effect_free, Qt); |
| 1096 | 1146 | ||
| 1097 | DEFSYM (QCobject_type, ":object-type"); | 1147 | DEFSYM (QCobject_type, ":object-type"); |
| 1148 | DEFSYM (QCarray_type, ":array-type"); | ||
| 1098 | DEFSYM (QCnull_object, ":null-object"); | 1149 | DEFSYM (QCnull_object, ":null-object"); |
| 1099 | DEFSYM (QCfalse_object, ":false-object"); | 1150 | DEFSYM (QCfalse_object, ":false-object"); |
| 1100 | DEFSYM (Qalist, "alist"); | 1151 | DEFSYM (Qalist, "alist"); |
| 1101 | DEFSYM (Qplist, "plist"); | 1152 | DEFSYM (Qplist, "plist"); |
| 1153 | DEFSYM (Qarray, "array"); | ||
| 1102 | 1154 | ||
| 1103 | defsubr (&Sjson_serialize); | 1155 | defsubr (&Sjson_serialize); |
| 1104 | defsubr (&Sjson_insert); | 1156 | defsubr (&Sjson_insert); |