removes all traces of unquoted key and comment support

This commit is contained in:
alisdair sullivan 2011-07-03 17:42:44 -07:00
parent e4cbe15fa7
commit e20e6746a2
19 changed files with 13 additions and 225 deletions

View file

@ -32,9 +32,7 @@
-type jsx_opts() :: [jsx_opt()].
-type jsx_opt() :: {comments, true | false}
| {escaped_unicode, ascii | codepoint | none}
| {unquoted_keys, true | false}
-type jsx_opt() :: {escaped_unicode, ascii | codepoint | none}
| {multi_term, true | false}
| {encoding, auto
| utf8
@ -109,8 +107,6 @@
-type decoder_opts() :: [decoder_opt()].
-type decoder_opt() :: {strict, true | false}
| {comments, true | false}
| {unquoted_keys, true | false}
| {encoding, supported_utf()}
| {label, atom | binary | existing_atom}
| {float, true | false}.
@ -118,16 +114,12 @@
-type verify_opts() :: [verify_opt()].
-type verify_opt() :: {strict, true | false}
| {encoding, auto | supported_utf()}
| {unquoted_keys, true | false}
| {comments, true | false}.
| {encoding, auto | supported_utf()}.
-type format_opts() :: [format_opt()].
-type format_opt() :: {strict, true | false}
| {encoding, auto | supported_utf()}
| {unquoted_keys, true | false}
| {comments, true | false}
| {space, integer()}
| space
| {indent, integer()}

View file

@ -30,9 +30,7 @@
%% opts record for decoder
-record(opts, {
comments = false,
escaped_unicode = codepoint,
unquoted_keys = false,
multi_term = false,
encoding = auto
}).
@ -71,8 +69,6 @@
-define(negative, 16#2D).
-define(positive, 16#2B).
%% comments
-define(star, 16#2a).
%% some useful guards
@ -137,20 +133,10 @@ parse_opts(Opts) ->
parse_opts(Opts, #opts{}).
parse_opts([], Opts) ->
Opts;
parse_opts([{comments, Value}|Rest], Opts) ->
true = lists:member(Value, [true, false]),
parse_opts(Rest, Opts#opts{comments=Value});
parse_opts([comments|Rest], Opts) ->
parse_opts(Rest, Opts#opts{comments=true});
Opts;
parse_opts([{escaped_unicode, Value}|Rest], Opts) ->
true = lists:member(Value, [ascii, codepoint, none]),
parse_opts(Rest, Opts#opts{escaped_unicode=Value});
parse_opts([{unquoted_keys, Value}|Rest], Opts) ->
true = lists:member(Value, [true, false]),
parse_opts(Rest, Opts#opts{unquoted_keys=Value});
parse_opts([unquoted_keys|Rest], Opts) ->
parse_opts(Rest, Opts#opts{unquoted_keys=true});
parse_opts([{multi_term, Value}|Rest], Opts) ->
true = lists:member(Value, [true, false]),
parse_opts(Rest, Opts#opts{multi_term=Value});
@ -183,8 +169,6 @@ start(<<?zero/?utfx, Rest/binary>>, Stack, Opts) ->
zero(Rest, Stack, Opts, "0");
start(<<S/?utfx, Rest/binary>>, Stack, Opts) when ?is_nonzero(S) ->
integer(Rest, Stack, Opts, [S]);
start(<<?solidus/?utfx, Rest/binary>>, Stack, #opts{comments=true}=Opts) ->
maybe_comment(Rest, fun(Resume) -> start(Resume, Stack, Opts) end);
start(Bin, Stack, Opts) ->
case ?partial_codepoint(Bin) of
true ->
@ -207,8 +191,6 @@ maybe_done(<<?comma/?utfx, Rest/binary>>, [object|Stack], Opts) ->
key(Rest, [key|Stack], Opts);
maybe_done(<<?comma/?utfx, Rest/binary>>, [array|_] = Stack, Opts) ->
value(Rest, Stack, Opts);
maybe_done(<<?solidus/?utfx, Rest/binary>>, Stack, #opts{comments=true}=Opts) ->
maybe_comment(Rest, fun(Resume) -> maybe_done(Resume, Stack, Opts) end);
maybe_done(Rest, [], #opts{multi_term=true}=Opts) ->
{event, end_json, fun() -> start(Rest, [], Opts) end};
maybe_done(Rest, [], Opts) ->
@ -227,8 +209,6 @@ maybe_done(Bin, Stack, Opts) ->
done(<<S/?utfx, Rest/binary>>, Opts) when ?is_whitespace(S) ->
done(Rest, Opts);
done(<<?solidus/?utfx, Rest/binary>>, #opts{comments=true}=Opts) ->
maybe_comment(Rest, fun(Resume) -> done(Resume, Opts) end);
done(<<>>, Opts) ->
{event, end_json, fun() ->
{incomplete, fun(end_stream) ->
@ -255,11 +235,6 @@ object(<<?quote/?utfx, Rest/binary>>, Stack, Opts) ->
string(Rest, Stack, Opts, []);
object(<<?end_object/?utfx, Rest/binary>>, [key|Stack], Opts) ->
{event, end_object, fun() -> maybe_done(Rest, Stack, Opts) end};
object(<<?solidus/?utfx, Rest/binary>>, Stack, #opts{comments=true}=Opts) ->
maybe_comment(Rest, fun(Resume) -> object(Resume, Stack, Opts) end);
object(<<S/?utfx, Rest/binary>>, Stack, #opts{unquoted_keys=true}=Opts)
when ?is_noncontrol(S) ->
unquoted_key(Rest, Stack, Opts, [S]);
object(Bin, Stack, Opts) ->
case ?partial_codepoint(Bin) of
true ->
@ -294,8 +269,6 @@ array(<<?start_array/?utfx, Rest/binary>>, Stack, Opts) ->
{event, start_array, fun() -> array(Rest, [array|Stack], Opts) end};
array(<<?end_array/?utfx, Rest/binary>>, [array|Stack], Opts) ->
{event, end_array, fun() -> maybe_done(Rest, Stack, Opts) end};
array(<<?solidus/?utfx, Rest/binary>>, Stack, #opts{comments=true}=Opts) ->
maybe_comment(Rest, fun(Resume) -> array(Resume, Stack, Opts) end);
array(Bin, Stack, Opts) ->
case ?partial_codepoint(Bin) of
true ->
@ -328,8 +301,6 @@ value(<<?start_object/?utfx, Rest/binary>>, Stack, Opts) ->
{event, start_object, fun() -> object(Rest, [key|Stack], Opts) end};
value(<<?start_array/?utfx, Rest/binary>>, Stack, Opts) ->
{event, start_array, fun() -> array(Rest, [array|Stack], Opts) end};
value(<<?solidus/?utfx, Rest/binary>>, Stack, #opts{comments=true}=Opts) ->
maybe_comment(Rest, fun(Resume) -> value(Resume, Stack, Opts) end);
value(Bin, Stack, Opts) ->
case ?partial_codepoint(Bin) of
true ->
@ -346,8 +317,6 @@ colon(<<S/?utfx, Rest/binary>>, Stack, Opts) when ?is_whitespace(S) ->
colon(Rest, Stack, Opts);
colon(<<?colon/?utfx, Rest/binary>>, [key|Stack], Opts) ->
value(Rest, [object|Stack], Opts);
colon(<<?solidus/?utfx, Rest/binary>>, Stack, #opts{comments=true}=Opts) ->
maybe_comment(Rest, fun(Resume) -> colon(Resume, Stack, Opts) end);
colon(Bin, Stack, Opts) ->
case ?partial_codepoint(Bin) of
true ->
@ -364,11 +333,6 @@ key(<<S/?utfx, Rest/binary>>, Stack, Opts) when ?is_whitespace(S) ->
key(Rest, Stack, Opts);
key(<<?quote/?utfx, Rest/binary>>, Stack, Opts) ->
string(Rest, Stack, Opts, []);
key(<<?solidus/?utfx, Rest/binary>>, Stack, #opts{comments=true}=Opts) ->
maybe_comment(Rest, fun(Resume) -> key(Resume, Stack, Opts) end);
key(<<S/?utfx, Rest/binary>>, Stack, #opts{unquoted_keys=true}=Opts)
when ?is_noncontrol(S) ->
unquoted_key(Rest, Stack, Opts, [S]);
key(Bin, Stack, Opts) ->
case ?partial_codepoint(Bin) of
true ->
@ -381,33 +345,6 @@ key(Bin, Stack, Opts) ->
end.
unquoted_key(<<S/?utfx, Rest/binary>>, Stack, Opts, Acc)
when ?is_whitespace(S) ->
{event, {key, lists:reverse(Acc)}, fun() -> colon(Rest, Stack, Opts) end};
unquoted_key(<<?colon/?utfx, Rest/binary>>, [key|Stack], Opts, Acc) ->
{event,
{key, lists:reverse(Acc)},
fun() -> value(Rest, [object|Stack], Opts) end
};
unquoted_key(<<S/?utfx, Rest/binary>>, Stack, Opts, Acc)
when ?is_noncontrol(S) ->
unquoted_key(Rest, Stack, Opts, [S] ++ Acc);
unquoted_key(Bin, Stack, Opts, Acc) ->
case partial_utf(Bin) of
true ->
{incomplete, fun(end_stream) ->
{error, {badjson, Bin}}
; (Stream) ->
unquoted_key(<<Bin/binary, Stream/binary>>,
Stack,
Opts,
Acc
)
end}
; false -> {error, {badjson, Bin}}
end.
%% string has an additional parameter, an accumulator (Acc) used to hold the
%% intermediate representation of the string being parsed. using a list of
%% integers representing unicode codepoints is faster than constructing
@ -649,8 +586,6 @@ zero(<<S/?utfx, Rest/binary>>, Stack, Opts, Acc) when ?is_whitespace(S) ->
{event, {integer, lists:reverse(Acc)}, fun() ->
maybe_done(Rest, Stack, Opts)
end};
zero(<<?solidus/?utfx, Rest/binary>>, Stack, #opts{comments=true}=Opts, Acc) ->
maybe_comment(Rest, fun(Resume) -> zero(Resume, Stack, Opts, Acc) end);
zero(<<>>, [], Opts, Acc) ->
{incomplete, fun(end_stream) ->
{event, {integer, lists:reverse(Acc)}, fun() ->
@ -700,12 +635,6 @@ integer(<<S/?utfx, Rest/binary>>, Stack, Opts, Acc) when ?is_whitespace(S) ->
{event, {integer, lists:reverse(Acc)}, fun() ->
maybe_done(Rest, Stack, Opts)
end};
integer(<<?solidus/?utfx, Rest/binary>>,
Stack,
#opts{comments=true}=Opts,
Acc
) ->
maybe_comment(Rest, fun(Resume) -> integer(Resume, Stack, Opts, Acc) end);
integer(<<>>, [], Opts, Acc) ->
{incomplete, fun(end_stream) ->
{event, {integer, lists:reverse(Acc)}, fun() ->
@ -774,12 +703,6 @@ decimal(<<S/?utfx, Rest/binary>>, Stack, Opts, Acc) when ?is_whitespace(S) ->
{event, {float, lists:reverse(Acc)}, fun() ->
maybe_done(Rest, Stack, Opts)
end};
decimal(<<?solidus/?utfx, Rest/binary>>,
Stack,
#opts{comments=true}=Opts,
Acc
) ->
maybe_comment(Rest, fun(Resume) -> decimal(Resume, Stack, Opts, Acc) end);
decimal(<<>>, [], Opts, Acc) ->
{incomplete, fun(end_stream) ->
{event, {float, lists:reverse(Acc)}, fun() ->
@ -856,8 +779,6 @@ exp(<<S/?utfx, Rest/binary>>, Stack, Opts, Acc) when ?is_whitespace(S) ->
{event, {float, lists:reverse(Acc)}, fun() ->
maybe_done(Rest, Stack, Opts)
end};
exp(<<?solidus/?utfx, Rest/binary>>, Stack, #opts{comments=true}=Opts, Acc) ->
maybe_comment(Rest, fun(Resume) -> exp(Resume, Stack, Opts, Acc) end);
exp(<<>>, [], Opts, Acc) ->
{incomplete, fun(end_stream) ->
{event, {float, lists:reverse(Acc)}, fun() ->
@ -1014,55 +935,4 @@ null(Bin, Stack, Opts) ->
null(<<Bin/binary, Stream/binary>>, Stack, Opts)
end}
; false -> {error, {badjson, Bin}}
end.
%% comments are c style, ex: /* blah blah */
%% any unicode character is valid in a comment except the */ sequence which
%% ends the comment. they're implemented as a closure called when the comment
%% ends that returns execution to the point where the comment began. comments
%% are not reported in any way, simply parsed.
maybe_comment(<<?star/?utfx, Rest/binary>>, Resume) ->
comment(Rest, Resume);
maybe_comment(Bin, Resume) ->
case ?partial_codepoint(Bin) of
true ->
{incomplete, fun(end_stream) ->
{error, {badjson, Bin}}
; (Stream) ->
maybe_comment(<<Bin/binary, Stream/binary>>, Resume)
end}
; false -> {error, {badjson, Bin}}
end.
comment(<<?star/?utfx, Rest/binary>>, Resume) ->
maybe_comment_done(Rest, Resume);
comment(<<_/?utfx, Rest/binary>>, Resume) ->
comment(Rest, Resume);
comment(Bin, Resume) ->
case ?partial_codepoint(Bin) of
true ->
{incomplete, fun(end_stream) ->
{error, {badjson, Bin}}
; (Stream) ->
comment(<<Bin/binary, Stream/binary>>, Resume)
end}
; false -> {error, {badjson, Bin}}
end.
maybe_comment_done(<<?solidus/?utfx, Rest/binary>>, Resume) ->
Resume(Rest);
maybe_comment_done(<<_/?utfx, Rest/binary>>, Resume) ->
comment(Rest, Resume);
maybe_comment_done(Bin, Resume) ->
case ?partial_codepoint(Bin) of
true ->
{incomplete, fun(end_stream) ->
{error, {badjson, Bin}}
; (Stream) ->
maybe_comment_done(<<Bin/binary, Stream/binary>>, Resume)
end}
; false -> {error, {badjson, Bin}}
end.

View file

@ -386,13 +386,7 @@ decode_test_() ->
{"strict mode", ?_assertError(badarg, json_to_term(<<"1.0">>,
[{strict, true}]
)
)},
{"comments",
?_assert(json_to_term(<<"[ /* a comment in an empty array */ ]">>,
[{comments, true}]
) =:= []
)
}
)}
].
encode_test_() ->

View file

@ -73,12 +73,12 @@ extract_parser_opts(Opts) ->
extract_parser_opts([], Acc) -> Acc;
extract_parser_opts([{K,V}|Rest], Acc) ->
case lists:member(K, [comments, encoding, unquoted_keys]) of
case lists:member(K, [encoding]) of
true -> [{K,V}] ++ Acc
; false -> extract_parser_opts(Rest, Acc)
end;
extract_parser_opts([K|Rest], Acc) ->
case lists:member(K, [comments, encoding, unquoted_keys]) of
case lists:member(K, [encoding]) of
true -> [K] ++ Acc
; false -> extract_parser_opts(Rest, Acc)
end.

View file

@ -52,12 +52,12 @@ extract_parser_opts(Opts) ->
extract_parser_opts([], Acc) -> Acc;
extract_parser_opts([{K,V}|Rest], Acc) ->
case lists:member(K, [comments, encoding, unquoted_keys]) of
case lists:member(K, [encoding]) of
true -> [{K,V}] ++ Acc
; false -> extract_parser_opts(Rest, Acc)
end;
extract_parser_opts([K|Rest], Acc) ->
case lists:member(K, [comments, encoding, unquoted_keys]) of
case lists:member(K, [encoding]) of
true -> [K] ++ Acc
; false -> extract_parser_opts(Rest, Acc)
end.
@ -158,15 +158,13 @@ false_test_() ->
{"trailing comma",
?_assert(is_json(<<"[ true, false, null, ]">>, []) =:= false)
},
{"unquoted key", ?_assert(is_json(<<"{ key: false }">>, []) =:= false)},
{"repeated key",
?_assert(is_json(
<<"{\"key\": true, \"key\": true}">>,
[]
) =:= false
)
},
{"comments", ?_assert(is_json(<<"[ /* a comment */ ]">>, []) =:= false)}
}
].
less_strict_test_() ->
@ -183,20 +181,6 @@ less_strict_test_() ->
[{strict, false}]
) =:= true
)
},
{"comments",
?_assert(is_json(
<<"[ /* a comment */ ]">>,
[{comments, true}]
) =:= true
)
},
{"unquoted keys",
?_assert(is_json(
<<"{unquotedkey : true}">>,
[{unquoted_keys, true}]
) =:= true
)
}
].

View file

@ -1 +0,0 @@
/*preceding comment*/ [/*array open comment*/ "a string"/*string comment*/, 1/*number comment*/, {/*object open comment*/"key"/*post key comment*/:/*colon comment*/[], /*pre key comment*/"another key": 0/*object close comment*/}, true/*literal comment*/] /*concluding comment*/

View file

@ -1,14 +0,0 @@
{name, "comments"}.
{jsx, [start_array,
{string,"a string"},
{integer,"1"},
start_object,
{key,"key"},
start_array,end_array,
{key,"another key"},
{integer,"0"},
end_object,
{literal,true},
end_array,end_json]}.
{json, "comments.json"}.
{jsx_flags, [{comments,true}]}.

View file

@ -1 +0,0 @@
[ /* this is a comment and should be ignored */ ]

View file

@ -1,4 +0,0 @@
{name, "empty_array_with_comment"}.
{jsx, [start_array,end_array,end_json]}.
{json, "empty_array_with_comment.json"}.
{jsx_flags, [{comments,true}]}.

View file

@ -1 +0,0 @@
{/*comment*/}

View file

@ -1,4 +0,0 @@
{name, "empty_object_with_comment"}.
{jsx, [start_object,end_object,end_json]}.
{json, "empty_object_with_comment.json"}.
{jsx_flags, [{comments,true}]}.

View file

@ -1 +1 @@
[[2.0e7], 2.0e7, {"key":2.0e7, "another key":2.0E7}, 4.2e70/*a comment*/ ]
[[2.0e7], 2.0e7, {"key":2.0e7, "another key":2.0E7}, 4.2e70 ]

View file

@ -12,4 +12,3 @@
{float,"4.2e70"},
end_array,end_json]}.
{json, "exp.json"}.
{jsx_flags, [{comments,true}]}.

View file

@ -1 +1 @@
[[2.0], 2.0, {"key":2.0e7, "another key":2.0E7}, {"key":2.0, "another key":2.0}, 4.2/*a comment*/ ]
[[2.0], 2.0, {"key":2.0e7, "another key":2.0E7}, {"key":2.0, "another key":2.0}, 4.2 ]

View file

@ -16,5 +16,4 @@
end_object,
{float,"4.2"},
end_array,end_json]}.
{json, "fraction.json"}.
{jsx_flags, [{comments,true}]}.
{json, "fraction.json"}.

View file

@ -1 +1 @@
[[20], 20, {"key":20, "another key":20}, 42/*a comment*/ ]
[[20], 20, {"key":20, "another key":20}, 42 ]

View file

@ -12,4 +12,3 @@
{integer,"42"},
end_array,end_json]}.
{json, "integer.json"}.
{jsx_flags, [{comments,true}]}.

View file

@ -1 +0,0 @@
{foo : "bar", baz:true, false : null,object:{ key : "value" },list:[null,null,null,[],"\n\r\\"]}

View file

@ -1,23 +0,0 @@
{name, "object with unquoted keys"}.
{jsx, [start_object,
{key,"foo"},
{string,"bar"},
{key,"baz"},
{literal,true},
{key,"false"},
{literal,null},
{key,"object"},
start_object,
{key,"key"},
{string,"value"},
end_object,
{key,"list"},
start_array,
{literal,null},
{literal,null},
{literal,null},
start_array,end_array,
{string,"\n\r\\"},
end_array,end_object,end_json]}.
{json, "object_with_unquoted_keys.json"}.
{jsx_flags, [{unquoted_keys, true}]}.