aboutsummaryrefslogtreecommitdiff
path: root/lua_cjson.c
diff options
context:
space:
mode:
authorskewb1k <skewb1kunix@gmail.com>2026-01-19 08:51:57 +0800
committerGitHub <noreply@github.com>2026-01-19 08:51:57 +0800
commitea05d06f5a56d94d423fc697561a33ca3b8bf085 (patch)
tree48fbfc307052ed233b9ccf0b39ee569b3467d244 /lua_cjson.c
parent3c64e2247623a66347a48d66b6a791b58a71fdbe (diff)
downloadlua-cjson-ea05d06f5a56d94d423fc697561a33ca3b8bf085.tar.gz
lua-cjson-ea05d06f5a56d94d423fc697561a33ca3b8bf085.tar.bz2
lua-cjson-ea05d06f5a56d94d423fc697561a33ca3b8bf085.zip
feature: add option to indent encoded output.HEADmaster
Diffstat (limited to '')
-rw-r--r--lua_cjson.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/lua_cjson.c b/lua_cjson.c
index 93b81e6..789817d 100644
--- a/lua_cjson.c
+++ b/lua_cjson.c
@@ -91,6 +91,7 @@
91#define DEFAULT_DECODE_ARRAY_WITH_ARRAY_MT 0 91#define DEFAULT_DECODE_ARRAY_WITH_ARRAY_MT 0
92#define DEFAULT_ENCODE_ESCAPE_FORWARD_SLASH 1 92#define DEFAULT_ENCODE_ESCAPE_FORWARD_SLASH 1
93#define DEFAULT_ENCODE_SKIP_UNSUPPORTED_VALUE_TYPES 0 93#define DEFAULT_ENCODE_SKIP_UNSUPPORTED_VALUE_TYPES 0
94#define DEFAULT_ENCODE_INDENT NULL
94 95
95#ifdef DISABLE_INVALID_NUMBERS 96#ifdef DISABLE_INVALID_NUMBERS
96#undef DEFAULT_DECODE_INVALID_NUMBERS 97#undef DEFAULT_DECODE_INVALID_NUMBERS
@@ -172,6 +173,7 @@ typedef struct {
172 int encode_keep_buffer; 173 int encode_keep_buffer;
173 int encode_empty_table_as_object; 174 int encode_empty_table_as_object;
174 int encode_escape_forward_slash; 175 int encode_escape_forward_slash;
176 const char *encode_indent;
175 177
176 int decode_invalid_numbers; 178 int decode_invalid_numbers;
177 int decode_max_depth; 179 int decode_max_depth;
@@ -310,6 +312,18 @@ static int json_enum_option(lua_State *l, int optindex, int *setting,
310 return 1; 312 return 1;
311} 313}
312 314
315/* Process string option for a configuration function */
316static int json_string_option(lua_State *l, int optindex, const char **setting)
317{
318 if (!lua_isnil(l, optindex)) {
319 const char *value = luaL_checkstring(l, optindex);
320 *setting = value;
321 }
322
323 lua_pushstring(l, *setting ? *setting : "");
324 return 1;
325}
326
313/* Configures handling of extremely sparse arrays: 327/* Configures handling of extremely sparse arrays:
314 * convert: Convert extremely sparse arrays into objects? Otherwise error. 328 * convert: Convert extremely sparse arrays into objects? Otherwise error.
315 * ratio: 0: always allow sparse; 1: never allow sparse; >1: use ratio 329 * ratio: 0: always allow sparse; 1: never allow sparse; >1: use ratio
@@ -400,6 +414,18 @@ static int json_cfg_encode_keep_buffer(lua_State *l)
400 return 1; 414 return 1;
401} 415}
402 416
417/* Configure how to indent output */
418static int json_cfg_encode_indent(lua_State *l)
419{
420 json_config_t *cfg = json_arg_init(l, 1);
421
422 json_string_option(l, 1, &cfg->encode_indent);
423 /* simplify further checking */
424 if (cfg->encode_indent[0] == '\0') cfg->encode_indent = NULL;
425
426 return 1;
427}
428
403#if defined(DISABLE_INVALID_NUMBERS) && !defined(USE_INTERNAL_FPCONV) 429#if defined(DISABLE_INVALID_NUMBERS) && !defined(USE_INTERNAL_FPCONV)
404void json_verify_invalid_number_setting(lua_State *l, int *setting) 430void json_verify_invalid_number_setting(lua_State *l, int *setting)
405{ 431{
@@ -491,6 +517,7 @@ static void json_create_config(lua_State *l)
491 cfg->decode_array_with_array_mt = DEFAULT_DECODE_ARRAY_WITH_ARRAY_MT; 517 cfg->decode_array_with_array_mt = DEFAULT_DECODE_ARRAY_WITH_ARRAY_MT;
492 cfg->encode_escape_forward_slash = DEFAULT_ENCODE_ESCAPE_FORWARD_SLASH; 518 cfg->encode_escape_forward_slash = DEFAULT_ENCODE_ESCAPE_FORWARD_SLASH;
493 cfg->encode_skip_unsupported_value_types = DEFAULT_ENCODE_SKIP_UNSUPPORTED_VALUE_TYPES; 519 cfg->encode_skip_unsupported_value_types = DEFAULT_ENCODE_SKIP_UNSUPPORTED_VALUE_TYPES;
520 cfg->encode_indent = DEFAULT_ENCODE_INDENT;
494 521
495#if DEFAULT_ENCODE_KEEP_BUFFER > 0 522#if DEFAULT_ENCODE_KEEP_BUFFER > 0
496 strbuf_init(&cfg->encode_buf, 0); 523 strbuf_init(&cfg->encode_buf, 0);
@@ -660,6 +687,13 @@ static void json_check_encode_depth(lua_State *l, json_config_t *cfg,
660static int json_append_data(lua_State *l, json_config_t *cfg, 687static int json_append_data(lua_State *l, json_config_t *cfg,
661 int current_depth, strbuf_t *json); 688 int current_depth, strbuf_t *json);
662 689
690static void json_append_newline_and_indent(strbuf_t *json, json_config_t *cfg, int depth)
691{
692 strbuf_append_char(json, '\n');
693 for (int i = 0; i < depth; i++)
694 strbuf_append_string(json, cfg->encode_indent);
695}
696
663/* json_append_array args: 697/* json_append_array args:
664 * - lua_State 698 * - lua_State
665 * - JSON strbuf 699 * - JSON strbuf
@@ -668,15 +702,21 @@ static void json_append_array(lua_State *l, json_config_t *cfg, int current_dept
668 strbuf_t *json, int array_length, int raw) 702 strbuf_t *json, int array_length, int raw)
669{ 703{
670 int comma, i, json_pos, err; 704 int comma, i, json_pos, err;
705 int has_items = 0;
671 706
672 strbuf_append_char(json, '['); 707 strbuf_append_char(json, '[');
673 708
674 comma = 0; 709 comma = 0;
675 for (i = 1; i <= array_length; i++) { 710 for (i = 1; i <= array_length; i++) {
711 has_items = 1;
712
676 json_pos = strbuf_length(json); 713 json_pos = strbuf_length(json);
677 if (comma++ > 0) 714 if (comma++ > 0)
678 strbuf_append_char(json, ','); 715 strbuf_append_char(json, ',');
679 716
717 if (cfg->encode_indent)
718 json_append_newline_and_indent(json, cfg, current_depth);
719
680 if (raw) { 720 if (raw) {
681 lua_rawgeti(l, -1, i); 721 lua_rawgeti(l, -1, i);
682 } else { 722 } else {
@@ -698,6 +738,9 @@ static void json_append_array(lua_State *l, json_config_t *cfg, int current_dept
698 lua_pop(l, 1); 738 lua_pop(l, 1);
699 } 739 }
700 740
741 if (has_items && cfg->encode_indent)
742 json_append_newline_and_indent(json, cfg, current_depth-1);
743
701 strbuf_append_char(json, ']'); 744 strbuf_append_char(json, ']');
702} 745}
703 746
@@ -752,6 +795,7 @@ static void json_append_object(lua_State *l, json_config_t *cfg,
752 int current_depth, strbuf_t *json) 795 int current_depth, strbuf_t *json)
753{ 796{
754 int comma, keytype, json_pos, err; 797 int comma, keytype, json_pos, err;
798 int has_items = 0;
755 799
756 /* Object */ 800 /* Object */
757 strbuf_append_char(json, '{'); 801 strbuf_append_char(json, '{');
@@ -760,10 +804,15 @@ static void json_append_object(lua_State *l, json_config_t *cfg,
760 /* table, startkey */ 804 /* table, startkey */
761 comma = 0; 805 comma = 0;
762 while (lua_next(l, -2) != 0) { 806 while (lua_next(l, -2) != 0) {
807 has_items = 1;
808
763 json_pos = strbuf_length(json); 809 json_pos = strbuf_length(json);
764 if (comma++ > 0) 810 if (comma++ > 0)
765 strbuf_append_char(json, ','); 811 strbuf_append_char(json, ',');
766 812
813 if (cfg->encode_indent)
814 json_append_newline_and_indent(json, cfg, current_depth);
815
767 /* table, key, value */ 816 /* table, key, value */
768 keytype = lua_type(l, -2); 817 keytype = lua_type(l, -2);
769 if (keytype == LUA_TNUMBER) { 818 if (keytype == LUA_TNUMBER) {
@@ -778,6 +827,9 @@ static void json_append_object(lua_State *l, json_config_t *cfg,
778 "table key must be a number or string"); 827 "table key must be a number or string");
779 /* never returns */ 828 /* never returns */
780 } 829 }
830 if (cfg->encode_indent)
831 strbuf_append_char(json, ' ');
832
781 833
782 /* table, key, value */ 834 /* table, key, value */
783 err = json_append_data(l, cfg, current_depth, json); 835 err = json_append_data(l, cfg, current_depth, json);
@@ -792,6 +844,9 @@ static void json_append_object(lua_State *l, json_config_t *cfg,
792 /* table, key */ 844 /* table, key */
793 } 845 }
794 846
847 if (has_items && cfg->encode_indent)
848 json_append_newline_and_indent(json, cfg, current_depth-1);
849
795 strbuf_append_char(json, '}'); 850 strbuf_append_char(json, '}');
796} 851}
797 852
@@ -1579,6 +1634,7 @@ static int lua_cjson_new(lua_State *l)
1579 { "decode_invalid_numbers", json_cfg_decode_invalid_numbers }, 1634 { "decode_invalid_numbers", json_cfg_decode_invalid_numbers },
1580 { "encode_escape_forward_slash", json_cfg_encode_escape_forward_slash }, 1635 { "encode_escape_forward_slash", json_cfg_encode_escape_forward_slash },
1581 { "encode_skip_unsupported_value_types", json_cfg_encode_skip_unsupported_value_types }, 1636 { "encode_skip_unsupported_value_types", json_cfg_encode_skip_unsupported_value_types },
1637 { "encode_indent", json_cfg_encode_indent },
1582 { "new", lua_cjson_new }, 1638 { "new", lua_cjson_new },
1583 { NULL, NULL } 1639 { NULL, NULL }
1584 }; 1640 };