Skip to content

Commit 5ce7142

Browse files
authored
Merge pull request ruby#680 from casperisfine/trailing-comma
Add option :allow_trailing_comma to JSON#parse
2 parents 4af700e + ef91aea commit 5ce7142

File tree

8 files changed

+1122
-391
lines changed

8 files changed

+1122
-391
lines changed

ext/json/ext/parser/parser.c

Lines changed: 677 additions & 233 deletions
Large diffs are not rendered by default.

ext/json/ext/parser/parser.rl

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ static ID i_json_creatable_p, i_json_create, i_create_id,
88
i_chr, i_deep_const_get, i_match, i_aset, i_aref,
99
i_leftshift, i_new, i_try_convert, i_uminus, i_encode;
1010

11-
static VALUE sym_max_nesting, sym_allow_nan, sym_symbolize_names, sym_freeze,
11+
static VALUE sym_max_nesting, sym_allow_nan, sym_allow_trailing_comma, sym_symbolize_names, sym_freeze,
1212
sym_create_additions, sym_create_id, sym_object_class, sym_array_class,
1313
sym_decimal_class, sym_match_string;
1414

@@ -383,6 +383,7 @@ typedef struct JSON_ParserStruct {
383383
FBuffer fbuffer;
384384
int max_nesting;
385385
bool allow_nan;
386+
bool allow_trailing_comma;
386387
bool parsing_name;
387388
bool symbolize_names;
388389
bool freeze;
@@ -477,6 +478,8 @@ static void raise_parse_error(const char *format, const char *start)
477478
}
478479
}
479480

481+
action allow_trailing_comma { json->allow_trailing_comma }
482+
480483
action parse_name {
481484
char *np;
482485
json->parsing_name = true;
@@ -495,7 +498,7 @@ static void raise_parse_error(const char *format, const char *start)
495498

496499
main := (
497500
begin_object
498-
(pair (next_pair)*)? ignore*
501+
(pair (next_pair)*((ignore* value_separator) when allow_trailing_comma)?)? ignore*
499502
end_object
500503
) @exit;
501504
}%%
@@ -788,13 +791,15 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
788791
}
789792
}
790793

794+
action allow_trailing_comma { json->allow_trailing_comma }
795+
791796
action exit { fhold; fbreak; }
792797

793798
next_element = value_separator ignore* begin_value >parse_value;
794799

795800
main := begin_array ignore*
796801
((begin_value >parse_value ignore*)
797-
(ignore* next_element ignore*)*)?
802+
(ignore* next_element ignore*)*((value_separator ignore*) when allow_trailing_comma)?)?
798803
end_array @exit;
799804
}%%
800805

@@ -1073,16 +1078,17 @@ static int configure_parser_i(VALUE key, VALUE val, VALUE data)
10731078
{
10741079
JSON_Parser *json = (JSON_Parser *)data;
10751080

1076-
if (key == sym_max_nesting) { json->max_nesting = RTEST(val) ? FIX2INT(val) : 0; }
1077-
else if (key == sym_allow_nan) { json->allow_nan = RTEST(val); }
1078-
else if (key == sym_symbolize_names) { json->symbolize_names = RTEST(val); }
1079-
else if (key == sym_freeze) { json->freeze = RTEST(val); }
1080-
else if (key == sym_create_id) { json->create_id = RTEST(val) ? val : Qfalse; }
1081-
else if (key == sym_object_class) { json->object_class = RTEST(val) ? val : Qfalse; }
1082-
else if (key == sym_array_class) { json->array_class = RTEST(val) ? val : Qfalse; }
1083-
else if (key == sym_decimal_class) { json->decimal_class = RTEST(val) ? val : Qfalse; }
1084-
else if (key == sym_match_string) { json->match_string = RTEST(val) ? val : Qfalse; }
1085-
else if (key == sym_create_additions) {
1081+
if (key == sym_max_nesting) { json->max_nesting = RTEST(val) ? FIX2INT(val) : 0; }
1082+
else if (key == sym_allow_nan) { json->allow_nan = RTEST(val); }
1083+
else if (key == sym_allow_trailing_comma) { json->allow_trailing_comma = RTEST(val); }
1084+
else if (key == sym_symbolize_names) { json->symbolize_names = RTEST(val); }
1085+
else if (key == sym_freeze) { json->freeze = RTEST(val); }
1086+
else if (key == sym_create_id) { json->create_id = RTEST(val) ? val : Qfalse; }
1087+
else if (key == sym_object_class) { json->object_class = RTEST(val) ? val : Qfalse; }
1088+
else if (key == sym_array_class) { json->array_class = RTEST(val) ? val : Qfalse; }
1089+
else if (key == sym_decimal_class) { json->decimal_class = RTEST(val) ? val : Qfalse; }
1090+
else if (key == sym_match_string) { json->match_string = RTEST(val) ? val : Qfalse; }
1091+
else if (key == sym_create_additions) {
10861092
if (NIL_P(val)) {
10871093
json->create_additions = true;
10881094
json->deprecated_create_additions = true;
@@ -1358,6 +1364,7 @@ void Init_parser(void)
13581364

13591365
sym_max_nesting = ID2SYM(rb_intern("max_nesting"));
13601366
sym_allow_nan = ID2SYM(rb_intern("allow_nan"));
1367+
sym_allow_trailing_comma = ID2SYM(rb_intern("allow_trailing_comma"));
13611368
sym_symbolize_names = ID2SYM(rb_intern("symbolize_names"));
13621369
sym_freeze = ID2SYM(rb_intern("freeze"));
13631370
sym_create_additions = ID2SYM(rb_intern("create_additions"));

0 commit comments

Comments
 (0)