From ff6a83598b8f14d4cdd4097f6f5af00a3f790551 Mon Sep 17 00:00:00 2001 From: alisdair sullivan Date: Tue, 12 Feb 2013 11:54:42 -0800 Subject: [PATCH] replace all incidences of opts with config --- src/jsx.erl | 41 +- src/{jsx_opts.hrl => jsx_config.hrl} | 2 +- src/jsx_decoder.erl | 1394 +++++++++++++------------- src/jsx_encoder.erl | 90 +- src/jsx_parser.erl | 194 ++-- src/jsx_to_json.erl | 212 ++-- src/jsx_to_term.erl | 134 +-- src/jsx_utils.erl | 732 +++++++------- src/jsx_verify.erl | 74 +- 9 files changed, 1436 insertions(+), 1437 deletions(-) rename src/{jsx_opts.hrl => jsx_config.hrl} (93%) diff --git a/src/jsx.erl b/src/jsx.erl index d953b8a..ec6cea4 100644 --- a/src/jsx.erl +++ b/src/jsx.erl @@ -22,7 +22,6 @@ -module(jsx). --compile(export_all). -export([encode/1, encode/2, decode/1, decode/2]). -export([is_json/1, is_json/2, is_term/1, is_term/2]). @@ -53,24 +52,24 @@ -spec encode(Source::json_term()) -> json_text() | {incomplete, encoder()}. --spec encode(Source::json_term(), Opts::jsx_to_json:opts()) -> json_text() | {incomplete, encoder()}. +-spec encode(Source::json_term(), Config::jsx_to_json:config()) -> json_text() | {incomplete, encoder()}. encode(Source) -> encode(Source, []). -encode(Source, Opts) -> jsx_to_json:to_json(Source, Opts). +encode(Source, Config) -> jsx_to_json:to_json(Source, Config). %% old api, alias for encode/x to_json(Source) -> encode(Source, []). -to_json(Source, Opts) -> encode(Source, Opts). +to_json(Source, Config) -> encode(Source, Config). term_to_json(Source) -> encode(Source, []). -term_to_json(Source, Opts) -> encode(Source, Opts). +term_to_json(Source, Config) -> encode(Source, Config). -spec format(Source::json_text()) -> json_text() | {incomplete, decoder()}. --spec format(Source::json_text(), Opts::jsx_to_json:opts()) -> json_text() | {incomplete, decoder()}. +-spec format(Source::json_text(), Config::jsx_to_json:config()) -> json_text() | {incomplete, decoder()}. format(Source) -> format(Source, []). -format(Source, Opts) -> jsx_to_json:format(Source, Opts). +format(Source, Config) -> jsx_to_json:format(Source, Config). -spec minify(Source::json_text()) -> json_text() | {incomplete, decoder()}. @@ -84,45 +83,45 @@ prettify(Source) -> format(Source, [space, {indent, 2}]). -spec decode(Source::json_text()) -> json_term() | {incomplete, decoder()}. --spec decode(Source::json_text(), Opts::jsx_to_term:opts()) -> json_term() | {incomplete, decoder()}. +-spec decode(Source::json_text(), Config::jsx_to_term:config()) -> json_term() | {incomplete, decoder()}. decode(Source) -> decode(Source, []). -decode(Source, Opts) -> jsx_to_term:to_term(Source, Opts). +decode(Source, Config) -> jsx_to_term:to_term(Source, Config). %% old api, alias for to_term/x to_term(Source) -> decode(Source, []). -to_term(Source, Opts) -> decode(Source, Opts). +to_term(Source, Config) -> decode(Source, Config). json_to_term(Source) -> decode(Source, []). -json_to_term(Source, Opts) -> decode(Source, Opts). +json_to_term(Source, Config) -> decode(Source, Config). -spec is_json(Source::any()) -> true | false. --spec is_json(Source::any(), Opts::jsx_verify:opts()) -> true | false. +-spec is_json(Source::any(), Config::jsx_verify:config()) -> true | false. is_json(Source) -> is_json(Source, []). -is_json(Source, Opts) -> jsx_verify:is_json(Source, Opts). +is_json(Source, Config) -> jsx_verify:is_json(Source, Config). -spec is_term(Source::any()) -> true | false. --spec is_term(Source::any(), Opts::jsx_verify:opts()) -> true | false. +-spec is_term(Source::any(), Config::jsx_verify:config()) -> true | false. is_term(Source) -> is_term(Source, []). -is_term(Source, Opts) -> jsx_verify:is_term(Source, Opts). +is_term(Source, Config) -> jsx_verify:is_term(Source, Config). -type decoder() :: fun((json_text() | end_stream) -> any()). --spec decoder(Handler::module(), State::any(), Opts::list()) -> decoder(). +-spec decoder(Handler::module(), State::any(), Config::list()) -> decoder(). -decoder(Handler, State, Opts) -> jsx_decoder:decoder(Handler, State, Opts). +decoder(Handler, State, Config) -> jsx_decoder:decoder(Handler, State, Config). -type encoder() :: fun((json_term() | end_stream) -> any()). --spec encoder(Handler::module(), State::any(), Opts::list()) -> encoder(). +-spec encoder(Handler::module(), State::any(), Config::list()) -> encoder(). -encoder(Handler, State, Opts) -> jsx_encoder:encoder(Handler, State, Opts). +encoder(Handler, State, Config) -> jsx_encoder:encoder(Handler, State, Config). -type token() :: [token()] @@ -149,6 +148,6 @@ encoder(Handler, State, Opts) -> jsx_encoder:encoder(Handler, State, Opts). -type parser() :: fun((token() | end_stream) -> any()). --spec parser(Handler::module(), State::any(), Opts::list()) -> parser(). +-spec parser(Handler::module(), State::any(), Config::list()) -> parser(). -parser(Handler, State, Opts) -> jsx_parser:parser(Handler, State, Opts). \ No newline at end of file +parser(Handler, State, Config) -> jsx_parser:parser(Handler, State, Config). \ No newline at end of file diff --git a/src/jsx_opts.hrl b/src/jsx_config.hrl similarity index 93% rename from src/jsx_opts.hrl rename to src/jsx_config.hrl index 6b3de90..502c29f 100644 --- a/src/jsx_opts.hrl +++ b/src/jsx_config.hrl @@ -1,4 +1,4 @@ --record(opts, { +-record(config, { replaced_bad_utf8 = false, escaped_forward_slashes = false, single_quoted_strings = false, diff --git a/src/jsx_decoder.erl b/src/jsx_decoder.erl index 93bac07..9d452dd 100644 --- a/src/jsx_decoder.erl +++ b/src/jsx_decoder.erl @@ -26,13 +26,13 @@ -export([decoder/3]). --spec decoder(Handler::module(), State::any(), Opts::jsx:opts()) -> jsx:decoder(). +-spec decoder(Handler::module(), State::any(), Config::jsx:config()) -> jsx:decoder(). -decoder(Handler, State, Opts) -> - fun(JSON) -> start(JSON, {Handler, Handler:init(State)}, [], jsx_utils:parse_opts(Opts)) end. +decoder(Handler, State, Config) -> + fun(JSON) -> start(JSON, {Handler, Handler:init(State)}, [], jsx_utils:parse_config(Config)) end. --include("jsx_opts.hrl"). +-include("jsx_config.hrl"). %% whitespace @@ -102,15 +102,15 @@ decoder(Handler, State, Opts) -> -ifndef(incomplete). --define(incomplete(State, Rest, Handler, Stack, Opts), +-define(incomplete(State, Rest, Handler, Stack, Config), {incomplete, fun(Stream) when is_binary(Stream) -> - State(<>, Handler, Stack, Opts) + State(<>, Handler, Stack, Config) ; (end_stream) -> case State(<>/binary>>, Handler, Stack, - Opts#opts{explicit_end=false}) of - {incomplete, _} -> ?error([Rest, Handler, Stack, Opts]) + Config#config{explicit_end=false}) of + {incomplete, _} -> ?error([Rest, Handler, Stack, Config]) ; Events -> Events end end @@ -128,117 +128,117 @@ decoder(Handler, State, Opts) -> -define(end_seq(Seq), unicode:characters_to_binary(lists:reverse(Seq))). -handle_event([], Handler, _Opts) -> Handler; -handle_event([Event|Rest], Handler, Opts) -> handle_event(Rest, handle_event(Event, Handler, Opts), Opts); -handle_event(Event, {Handler, State}, _Opts) -> {Handler, Handler:handle_event(Event, State)}. +handle_event([], Handler, _Config) -> Handler; +handle_event([Event|Rest], Handler, Config) -> handle_event(Rest, handle_event(Event, Handler, Config), Config); +handle_event(Event, {Handler, State}, _Config) -> {Handler, Handler:handle_event(Event, State)}. -start(<<16#ef, Rest/binary>>, Handler, Stack, Opts) -> - maybe_bom(Rest, Handler, Stack, Opts); -start(<<>>, Handler, Stack, Opts) -> - ?incomplete(start, <<>>, Handler, Stack, Opts); -start(Bin, Handler, Stack, Opts) -> - value(Bin, Handler, Stack, Opts). +start(<<16#ef, Rest/binary>>, Handler, Stack, Config) -> + maybe_bom(Rest, Handler, Stack, Config); +start(<<>>, Handler, Stack, Config) -> + ?incomplete(start, <<>>, Handler, Stack, Config); +start(Bin, Handler, Stack, Config) -> + value(Bin, Handler, Stack, Config). -maybe_bom(<<16#bb, Rest/binary>>, Handler, Stack, Opts) -> - definitely_bom(Rest, Handler, Stack, Opts); -maybe_bom(<<>>, Handler, Stack, Opts) -> - ?incomplete(maybe_bom, <<>>, Handler, Stack, Opts); -maybe_bom(Bin, Handler, Stack, Opts) -> - ?error([Bin, Handler, Stack, Opts]). +maybe_bom(<<16#bb, Rest/binary>>, Handler, Stack, Config) -> + definitely_bom(Rest, Handler, Stack, Config); +maybe_bom(<<>>, Handler, Stack, Config) -> + ?incomplete(maybe_bom, <<>>, Handler, Stack, Config); +maybe_bom(Bin, Handler, Stack, Config) -> + ?error([Bin, Handler, Stack, Config]). -definitely_bom(<<16#bf, Rest/binary>>, Handler, Stack, Opts) -> - value(Rest, Handler, Stack, Opts); -definitely_bom(<<>>, Handler, Stack, Opts) -> - ?incomplete(definitely_bom, <<>>, Handler, Stack, Opts); -definitely_bom(Bin, Handler, Stack, Opts) -> - ?error([Bin, Handler, Stack, Opts]). +definitely_bom(<<16#bf, Rest/binary>>, Handler, Stack, Config) -> + value(Rest, Handler, Stack, Config); +definitely_bom(<<>>, Handler, Stack, Config) -> + ?incomplete(definitely_bom, <<>>, Handler, Stack, Config); +definitely_bom(Bin, Handler, Stack, Config) -> + ?error([Bin, Handler, Stack, Config]). -value(<>, Handler, Stack, Opts) -> - string(Rest, Handler, [?new_seq()|Stack], Opts); -value(<>, Handler, Stack, Opts = #opts{single_quoted_strings=true}) -> - string(Rest, Handler, [?new_seq(), single_quote|Stack], Opts); -value(<<$t, Rest/binary>>, Handler, Stack, Opts) -> - tr(Rest, Handler, Stack, Opts); -value(<<$f, Rest/binary>>, Handler, Stack, Opts) -> - fa(Rest, Handler, Stack, Opts); -value(<<$n, Rest/binary>>, Handler, Stack, Opts) -> - nu(Rest, Handler, Stack, Opts); -value(<>, Handler, Stack, Opts) -> - negative(Rest, Handler, [[$-]|Stack], Opts); -value(<>, Handler, Stack, Opts) -> - zero(Rest, Handler, [[$0]|Stack], Opts); -value(<>, Handler, Stack, Opts) when ?is_nonzero(S) -> - integer(Rest, Handler, [[S]|Stack], Opts); -value(<>, Handler, Stack, Opts) -> - object(Rest, handle_event(start_object, Handler, Opts), [key|Stack], Opts); -value(<>, Handler, Stack, Opts) -> - array(Rest, handle_event(start_array, Handler, Opts), [array|Stack], Opts); -value(<>, Handler, Stack, Opts) when ?is_whitespace(S) -> - value(Rest, Handler, Stack, Opts); -value(<>, Handler, Stack, Opts=#opts{comments=true}) -> - comment(Rest, Handler, [value|Stack], Opts); -value(<<>>, Handler, Stack, Opts) -> - ?incomplete(value, <<>>, Handler, Stack, Opts); -value(Bin, Handler, Stack, Opts) -> - ?error([Bin, Handler, Stack, Opts]). +value(<>, Handler, Stack, Config) -> + string(Rest, Handler, [?new_seq()|Stack], Config); +value(<>, Handler, Stack, Config = #config{single_quoted_strings=true}) -> + string(Rest, Handler, [?new_seq(), single_quote|Stack], Config); +value(<<$t, Rest/binary>>, Handler, Stack, Config) -> + tr(Rest, Handler, Stack, Config); +value(<<$f, Rest/binary>>, Handler, Stack, Config) -> + fa(Rest, Handler, Stack, Config); +value(<<$n, Rest/binary>>, Handler, Stack, Config) -> + nu(Rest, Handler, Stack, Config); +value(<>, Handler, Stack, Config) -> + negative(Rest, Handler, [[$-]|Stack], Config); +value(<>, Handler, Stack, Config) -> + zero(Rest, Handler, [[$0]|Stack], Config); +value(<>, Handler, Stack, Config) when ?is_nonzero(S) -> + integer(Rest, Handler, [[S]|Stack], Config); +value(<>, Handler, Stack, Config) -> + object(Rest, handle_event(start_object, Handler, Config), [key|Stack], Config); +value(<>, Handler, Stack, Config) -> + array(Rest, handle_event(start_array, Handler, Config), [array|Stack], Config); +value(<>, Handler, Stack, Config) when ?is_whitespace(S) -> + value(Rest, Handler, Stack, Config); +value(<>, Handler, Stack, Config=#config{comments=true}) -> + comment(Rest, Handler, [value|Stack], Config); +value(<<>>, Handler, Stack, Config) -> + ?incomplete(value, <<>>, Handler, Stack, Config); +value(Bin, Handler, Stack, Config) -> + ?error([Bin, Handler, Stack, Config]). -object(<>, Handler, Stack, Opts) -> - string(Rest, Handler, [?new_seq()|Stack], Opts); -object(<>, Handler, Stack, Opts = #opts{single_quoted_strings=true}) -> - string(Rest, Handler, [?new_seq(), single_quote|Stack], Opts); -object(<>, Handler, [key|Stack], Opts) -> - maybe_done(Rest, handle_event(end_object, Handler, Opts), Stack, Opts); -object(<>, Handler, Stack, Opts) when ?is_whitespace(S) -> - object(Rest, Handler, Stack, Opts); -object(<>, Handler, Stack, Opts=#opts{comments=true}) -> - comment(Rest, Handler, [object|Stack], Opts); -object(<<>>, Handler, Stack, Opts) -> - ?incomplete(object, <<>>, Handler, Stack, Opts); -object(Bin, Handler, Stack, Opts) -> - ?error([Bin, Handler, Stack, Opts]). +object(<>, Handler, Stack, Config) -> + string(Rest, Handler, [?new_seq()|Stack], Config); +object(<>, Handler, Stack, Config = #config{single_quoted_strings=true}) -> + string(Rest, Handler, [?new_seq(), single_quote|Stack], Config); +object(<>, Handler, [key|Stack], Config) -> + maybe_done(Rest, handle_event(end_object, Handler, Config), Stack, Config); +object(<>, Handler, Stack, Config) when ?is_whitespace(S) -> + object(Rest, Handler, Stack, Config); +object(<>, Handler, Stack, Config=#config{comments=true}) -> + comment(Rest, Handler, [object|Stack], Config); +object(<<>>, Handler, Stack, Config) -> + ?incomplete(object, <<>>, Handler, Stack, Config); +object(Bin, Handler, Stack, Config) -> + ?error([Bin, Handler, Stack, Config]). -array(<>, Handler, [array|Stack], Opts) -> - maybe_done(Rest, handle_event(end_array, Handler, Opts), Stack, Opts); -array(<>, Handler, Stack, Opts) when ?is_whitespace(S) -> - array(Rest, Handler, Stack, Opts); -array(<>, Handler, Stack, Opts=#opts{comments=true}) -> - comment(Rest, Handler, [array|Stack], Opts); -array(<<>>, Handler, Stack, Opts) -> - ?incomplete(array, <<>>, Handler, Stack, Opts); -array(Bin, Handler, Stack, Opts) -> - value(Bin, Handler, Stack, Opts). +array(<>, Handler, [array|Stack], Config) -> + maybe_done(Rest, handle_event(end_array, Handler, Config), Stack, Config); +array(<>, Handler, Stack, Config) when ?is_whitespace(S) -> + array(Rest, Handler, Stack, Config); +array(<>, Handler, Stack, Config=#config{comments=true}) -> + comment(Rest, Handler, [array|Stack], Config); +array(<<>>, Handler, Stack, Config) -> + ?incomplete(array, <<>>, Handler, Stack, Config); +array(Bin, Handler, Stack, Config) -> + value(Bin, Handler, Stack, Config). -colon(<>, Handler, [key|Stack], Opts) -> - value(Rest, Handler, [object|Stack], Opts); -colon(<>, Handler, Stack, Opts) when ?is_whitespace(S) -> - colon(Rest, Handler, Stack, Opts); -colon(<>, Handler, Stack, Opts=#opts{comments=true}) -> - comment(Rest, Handler, [colon|Stack], Opts); -colon(<<>>, Handler, Stack, Opts) -> - ?incomplete(colon, <<>>, Handler, Stack, Opts); -colon(Bin, Handler, Stack, Opts) -> - ?error([Bin, Handler, Stack, Opts]). +colon(<>, Handler, [key|Stack], Config) -> + value(Rest, Handler, [object|Stack], Config); +colon(<>, Handler, Stack, Config) when ?is_whitespace(S) -> + colon(Rest, Handler, Stack, Config); +colon(<>, Handler, Stack, Config=#config{comments=true}) -> + comment(Rest, Handler, [colon|Stack], Config); +colon(<<>>, Handler, Stack, Config) -> + ?incomplete(colon, <<>>, Handler, Stack, Config); +colon(Bin, Handler, Stack, Config) -> + ?error([Bin, Handler, Stack, Config]). -key(<>, Handler, Stack, Opts) -> - string(Rest, Handler, [?new_seq()|Stack], Opts); -key(<>, Handler, Stack, Opts = #opts{single_quoted_strings=true}) -> - string(Rest, Handler, [?new_seq(), single_quote|Stack], Opts); -key(<>, Handler, Stack, Opts) when ?is_whitespace(S) -> - key(Rest, Handler, Stack, Opts); -key(<>, Handler, Stack, Opts=#opts{comments=true}) -> - comment(Rest, Handler, [key|Stack], Opts); -key(<<>>, Handler, Stack, Opts) -> - ?incomplete(key, <<>>, Handler, Stack, Opts); -key(Bin, Handler, Stack, Opts) -> - ?error([Bin, Handler, Stack, Opts]). +key(<>, Handler, Stack, Config) -> + string(Rest, Handler, [?new_seq()|Stack], Config); +key(<>, Handler, Stack, Config = #config{single_quoted_strings=true}) -> + string(Rest, Handler, [?new_seq(), single_quote|Stack], Config); +key(<>, Handler, Stack, Config) when ?is_whitespace(S) -> + key(Rest, Handler, Stack, Config); +key(<>, Handler, Stack, Config=#config{comments=true}) -> + comment(Rest, Handler, [key|Stack], Config); +key(<<>>, Handler, Stack, Config) -> + ?incomplete(key, <<>>, Handler, Stack, Config); +key(Bin, Handler, Stack, Config) -> + ?error([Bin, Handler, Stack, Config]). %% string appends it's output to the term at the top of the stack. for @@ -260,271 +260,271 @@ partial_utf(_) -> false. %% explicitly whitelist ascii set for better efficiency (seriously, it's worth %% almost a 20% increase) -string(<<32, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 32)|Stack], Opts); -string(<<33, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 33)|Stack], Opts); -string(<>, Handler, S, Opts) -> +string(<<32, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 32)|Stack], Config); +string(<<33, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 33)|Stack], Config); +string(<>, Handler, S, Config) -> case S of [Acc, key|Stack] -> - colon(Rest, handle_event({key, ?end_seq(Acc)}, Handler, Opts), [key|Stack], Opts); + colon(Rest, handle_event({key, ?end_seq(Acc)}, Handler, Config), [key|Stack], Config); [_Acc, single_quote|_Stack] -> - ?error([<>, Handler, S, Opts]); + ?error([<>, Handler, S, Config]); [Acc|Stack] -> - maybe_done(Rest, handle_event({string, ?end_seq(Acc)}, Handler, Opts), Stack, Opts) + maybe_done(Rest, handle_event({string, ?end_seq(Acc)}, Handler, Config), Stack, Config) end; -string(<<35, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 35)|Stack], Opts); -string(<<36, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 36)|Stack], Opts); -string(<<37, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 37)|Stack], Opts); -string(<<38, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 38)|Stack], Opts); -string(<>, Handler, [Acc|Stack], Opts) -> - case Opts#opts.single_quoted_strings of +string(<<35, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 35)|Stack], Config); +string(<<36, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 36)|Stack], Config); +string(<<37, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 37)|Stack], Config); +string(<<38, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 38)|Stack], Config); +string(<>, Handler, [Acc|Stack], Config) -> + case Config#config.single_quoted_strings of true -> case Stack of [single_quote, key|S] -> - colon(Rest, handle_event({key, ?end_seq(Acc)}, Handler, Opts), [key|S], Opts) + colon(Rest, handle_event({key, ?end_seq(Acc)}, Handler, Config), [key|S], Config) ; [single_quote|S] -> - maybe_done(Rest, handle_event({string, ?end_seq(Acc)}, Handler, Opts), S, Opts) + maybe_done(Rest, handle_event({string, ?end_seq(Acc)}, Handler, Config), S, Config) ; _ -> - string(Rest, Handler, [?acc_seq(Acc, maybe_replace(?singlequote, Opts))|Stack], Opts) + string(Rest, Handler, [?acc_seq(Acc, maybe_replace(?singlequote, Config))|Stack], Config) end ; false -> - string(Rest, Handler, [?acc_seq(Acc, ?singlequote)|Stack], Opts) + string(Rest, Handler, [?acc_seq(Acc, ?singlequote)|Stack], Config) end; -string(<<40, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 40)|Stack], Opts); -string(<<41, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 41)|Stack], Opts); -string(<<42, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 42)|Stack], Opts); -string(<<43, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 43)|Stack], Opts); -string(<<44, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 44)|Stack], Opts); -string(<<45, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 45)|Stack], Opts); -string(<<46, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 46)|Stack], Opts); -string(<<$/, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, maybe_replace($/, Opts))|Stack], Opts); -string(<<48, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 48)|Stack], Opts); -string(<<49, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 49)|Stack], Opts); -string(<<50, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 50)|Stack], Opts); -string(<<51, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 51)|Stack], Opts); -string(<<52, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 52)|Stack], Opts); -string(<<53, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 53)|Stack], Opts); -string(<<54, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 54)|Stack], Opts); -string(<<55, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 55)|Stack], Opts); -string(<<56, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 56)|Stack], Opts); -string(<<57, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 57)|Stack], Opts); -string(<<58, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 58)|Stack], Opts); -string(<<59, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 59)|Stack], Opts); -string(<<60, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 60)|Stack], Opts); -string(<<61, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 61)|Stack], Opts); -string(<<62, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 62)|Stack], Opts); -string(<<63, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 63)|Stack], Opts); -string(<<64, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 64)|Stack], Opts); -string(<<65, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 65)|Stack], Opts); -string(<<66, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 66)|Stack], Opts); -string(<<67, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 67)|Stack], Opts); -string(<<68, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 68)|Stack], Opts); -string(<<69, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 69)|Stack], Opts); -string(<<70, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 70)|Stack], Opts); -string(<<71, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 71)|Stack], Opts); -string(<<72, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 72)|Stack], Opts); -string(<<73, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 73)|Stack], Opts); -string(<<74, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 74)|Stack], Opts); -string(<<75, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 75)|Stack], Opts); -string(<<76, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 76)|Stack], Opts); -string(<<77, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 77)|Stack], Opts); -string(<<78, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 78)|Stack], Opts); -string(<<79, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 79)|Stack], Opts); -string(<<80, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 80)|Stack], Opts); -string(<<81, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 81)|Stack], Opts); -string(<<82, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 82)|Stack], Opts); -string(<<83, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 83)|Stack], Opts); -string(<<84, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 84)|Stack], Opts); -string(<<85, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 85)|Stack], Opts); -string(<<86, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 86)|Stack], Opts); -string(<<87, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 87)|Stack], Opts); -string(<<88, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 88)|Stack], Opts); -string(<<89, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 89)|Stack], Opts); -string(<<90, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 90)|Stack], Opts); -string(<<91, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 91)|Stack], Opts); -string(<>, Handler, Stack, Opts) -> - escape(Rest, Handler, Stack, Opts); -string(<<93, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 93)|Stack], Opts); -string(<<94, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 94)|Stack], Opts); -string(<<95, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 95)|Stack], Opts); -string(<<96, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 96)|Stack], Opts); -string(<<97, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 97)|Stack], Opts); -string(<<98, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 98)|Stack], Opts); -string(<<99, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 99)|Stack], Opts); -string(<<100, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 100)|Stack], Opts); -string(<<101, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 101)|Stack], Opts); -string(<<102, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 102)|Stack], Opts); -string(<<103, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 103)|Stack], Opts); -string(<<104, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 104)|Stack], Opts); -string(<<105, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 105)|Stack], Opts); -string(<<106, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 106)|Stack], Opts); -string(<<107, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 107)|Stack], Opts); -string(<<108, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 108)|Stack], Opts); -string(<<109, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 109)|Stack], Opts); -string(<<110, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 110)|Stack], Opts); -string(<<111, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 111)|Stack], Opts); -string(<<112, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 112)|Stack], Opts); -string(<<113, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 113)|Stack], Opts); -string(<<114, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 114)|Stack], Opts); -string(<<115, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 115)|Stack], Opts); -string(<<116, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 116)|Stack], Opts); -string(<<117, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 117)|Stack], Opts); -string(<<118, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 118)|Stack], Opts); -string(<<119, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 119)|Stack], Opts); -string(<<120, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 120)|Stack], Opts); -string(<<121, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 121)|Stack], Opts); -string(<<122, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 122)|Stack], Opts); -string(<<123, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 123)|Stack], Opts); -string(<<124, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 124)|Stack], Opts); -string(<<125, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 125)|Stack], Opts); -string(<<126, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 126)|Stack], Opts); -string(<<127, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 127)|Stack], Opts); -string(<>, Handler, [Acc|Stack], Opts) when X >= 16#20, X < 16#2028 -> - string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Opts); -string(<>, Handler, [Acc|Stack], Opts) when X == 16#2028; X == 16#2029 -> - string(Rest, Handler, [?acc_seq(Acc, maybe_replace(X, Opts))|Stack], Opts); -string(<>, Handler, [Acc|Stack], Opts) when X > 16#2029, X < 16#d800 -> - string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Opts); -string(<>, Handler, [Acc|Stack], Opts) when X > 16#dfff, X < 16#fdd0 -> - string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Opts); -string(<>, Handler, [Acc|Stack], Opts) when X > 16#fdef, X < 16#fffe -> - string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Opts); -string(<>, Handler, [Acc|Stack], Opts) when X >= 16#10000, X < 16#1fffe -> - string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Opts); -string(<>, Handler, [Acc|Stack], Opts) when X >= 16#20000, X < 16#2fffe -> - string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Opts); -string(<>, Handler, [Acc|Stack], Opts) when X >= 16#30000, X < 16#3fffe -> - string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Opts); -string(<>, Handler, [Acc|Stack], Opts) when X >= 16#40000, X < 16#4fffe -> - string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Opts); -string(<>, Handler, [Acc|Stack], Opts) when X >= 16#50000, X < 16#5fffe -> - string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Opts); -string(<>, Handler, [Acc|Stack], Opts) when X >= 16#60000, X < 16#6fffe -> - string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Opts); -string(<>, Handler, [Acc|Stack], Opts) when X >= 16#70000, X < 16#7fffe -> - string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Opts); -string(<>, Handler, [Acc|Stack], Opts) when X >= 16#80000, X < 16#8fffe -> - string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Opts); -string(<>, Handler, [Acc|Stack], Opts) when X >= 16#90000, X < 16#9fffe -> - string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Opts); -string(<>, Handler, [Acc|Stack], Opts) when X >= 16#a0000, X < 16#afffe -> - string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Opts); -string(<>, Handler, [Acc|Stack], Opts) when X >= 16#b0000, X < 16#bfffe -> - string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Opts); -string(<>, Handler, [Acc|Stack], Opts) when X >= 16#c0000, X < 16#cfffe -> - string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Opts); -string(<>, Handler, [Acc|Stack], Opts) when X >= 16#d0000, X < 16#dfffe -> - string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Opts); -string(<>, Handler, [Acc|Stack], Opts) when X >= 16#e0000, X < 16#efffe -> - string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Opts); -string(<>, Handler, [Acc|Stack], Opts) when X >= 16#f0000, X < 16#ffffe -> - string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Opts); -string(<>, Handler, [Acc|Stack], Opts) when X >= 16#100000, X < 16#10fffe -> - string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Opts); -string(<>, Handler, [Acc|Stack], Opts) -> - case Opts#opts.replaced_bad_utf8 of - true -> noncharacter(<>, Handler, [Acc|Stack], Opts) - ; false -> ?error([<>, Handler, [Acc|Stack], Opts]) +string(<<40, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 40)|Stack], Config); +string(<<41, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 41)|Stack], Config); +string(<<42, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 42)|Stack], Config); +string(<<43, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 43)|Stack], Config); +string(<<44, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 44)|Stack], Config); +string(<<45, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 45)|Stack], Config); +string(<<46, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 46)|Stack], Config); +string(<<$/, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, maybe_replace($/, Config))|Stack], Config); +string(<<48, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 48)|Stack], Config); +string(<<49, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 49)|Stack], Config); +string(<<50, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 50)|Stack], Config); +string(<<51, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 51)|Stack], Config); +string(<<52, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 52)|Stack], Config); +string(<<53, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 53)|Stack], Config); +string(<<54, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 54)|Stack], Config); +string(<<55, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 55)|Stack], Config); +string(<<56, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 56)|Stack], Config); +string(<<57, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 57)|Stack], Config); +string(<<58, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 58)|Stack], Config); +string(<<59, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 59)|Stack], Config); +string(<<60, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 60)|Stack], Config); +string(<<61, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 61)|Stack], Config); +string(<<62, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 62)|Stack], Config); +string(<<63, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 63)|Stack], Config); +string(<<64, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 64)|Stack], Config); +string(<<65, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 65)|Stack], Config); +string(<<66, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 66)|Stack], Config); +string(<<67, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 67)|Stack], Config); +string(<<68, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 68)|Stack], Config); +string(<<69, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 69)|Stack], Config); +string(<<70, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 70)|Stack], Config); +string(<<71, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 71)|Stack], Config); +string(<<72, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 72)|Stack], Config); +string(<<73, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 73)|Stack], Config); +string(<<74, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 74)|Stack], Config); +string(<<75, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 75)|Stack], Config); +string(<<76, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 76)|Stack], Config); +string(<<77, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 77)|Stack], Config); +string(<<78, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 78)|Stack], Config); +string(<<79, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 79)|Stack], Config); +string(<<80, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 80)|Stack], Config); +string(<<81, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 81)|Stack], Config); +string(<<82, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 82)|Stack], Config); +string(<<83, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 83)|Stack], Config); +string(<<84, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 84)|Stack], Config); +string(<<85, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 85)|Stack], Config); +string(<<86, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 86)|Stack], Config); +string(<<87, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 87)|Stack], Config); +string(<<88, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 88)|Stack], Config); +string(<<89, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 89)|Stack], Config); +string(<<90, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 90)|Stack], Config); +string(<<91, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 91)|Stack], Config); +string(<>, Handler, Stack, Config) -> + escape(Rest, Handler, Stack, Config); +string(<<93, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 93)|Stack], Config); +string(<<94, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 94)|Stack], Config); +string(<<95, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 95)|Stack], Config); +string(<<96, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 96)|Stack], Config); +string(<<97, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 97)|Stack], Config); +string(<<98, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 98)|Stack], Config); +string(<<99, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 99)|Stack], Config); +string(<<100, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 100)|Stack], Config); +string(<<101, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 101)|Stack], Config); +string(<<102, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 102)|Stack], Config); +string(<<103, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 103)|Stack], Config); +string(<<104, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 104)|Stack], Config); +string(<<105, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 105)|Stack], Config); +string(<<106, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 106)|Stack], Config); +string(<<107, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 107)|Stack], Config); +string(<<108, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 108)|Stack], Config); +string(<<109, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 109)|Stack], Config); +string(<<110, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 110)|Stack], Config); +string(<<111, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 111)|Stack], Config); +string(<<112, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 112)|Stack], Config); +string(<<113, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 113)|Stack], Config); +string(<<114, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 114)|Stack], Config); +string(<<115, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 115)|Stack], Config); +string(<<116, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 116)|Stack], Config); +string(<<117, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 117)|Stack], Config); +string(<<118, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 118)|Stack], Config); +string(<<119, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 119)|Stack], Config); +string(<<120, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 120)|Stack], Config); +string(<<121, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 121)|Stack], Config); +string(<<122, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 122)|Stack], Config); +string(<<123, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 123)|Stack], Config); +string(<<124, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 124)|Stack], Config); +string(<<125, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 125)|Stack], Config); +string(<<126, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 126)|Stack], Config); +string(<<127, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 127)|Stack], Config); +string(<>, Handler, [Acc|Stack], Config) when X >= 16#20, X < 16#2028 -> + string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Config); +string(<>, Handler, [Acc|Stack], Config) when X == 16#2028; X == 16#2029 -> + string(Rest, Handler, [?acc_seq(Acc, maybe_replace(X, Config))|Stack], Config); +string(<>, Handler, [Acc|Stack], Config) when X > 16#2029, X < 16#d800 -> + string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Config); +string(<>, Handler, [Acc|Stack], Config) when X > 16#dfff, X < 16#fdd0 -> + string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Config); +string(<>, Handler, [Acc|Stack], Config) when X > 16#fdef, X < 16#fffe -> + string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Config); +string(<>, Handler, [Acc|Stack], Config) when X >= 16#10000, X < 16#1fffe -> + string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Config); +string(<>, Handler, [Acc|Stack], Config) when X >= 16#20000, X < 16#2fffe -> + string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Config); +string(<>, Handler, [Acc|Stack], Config) when X >= 16#30000, X < 16#3fffe -> + string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Config); +string(<>, Handler, [Acc|Stack], Config) when X >= 16#40000, X < 16#4fffe -> + string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Config); +string(<>, Handler, [Acc|Stack], Config) when X >= 16#50000, X < 16#5fffe -> + string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Config); +string(<>, Handler, [Acc|Stack], Config) when X >= 16#60000, X < 16#6fffe -> + string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Config); +string(<>, Handler, [Acc|Stack], Config) when X >= 16#70000, X < 16#7fffe -> + string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Config); +string(<>, Handler, [Acc|Stack], Config) when X >= 16#80000, X < 16#8fffe -> + string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Config); +string(<>, Handler, [Acc|Stack], Config) when X >= 16#90000, X < 16#9fffe -> + string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Config); +string(<>, Handler, [Acc|Stack], Config) when X >= 16#a0000, X < 16#afffe -> + string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Config); +string(<>, Handler, [Acc|Stack], Config) when X >= 16#b0000, X < 16#bfffe -> + string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Config); +string(<>, Handler, [Acc|Stack], Config) when X >= 16#c0000, X < 16#cfffe -> + string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Config); +string(<>, Handler, [Acc|Stack], Config) when X >= 16#d0000, X < 16#dfffe -> + string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Config); +string(<>, Handler, [Acc|Stack], Config) when X >= 16#e0000, X < 16#efffe -> + string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Config); +string(<>, Handler, [Acc|Stack], Config) when X >= 16#f0000, X < 16#ffffe -> + string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Config); +string(<>, Handler, [Acc|Stack], Config) when X >= 16#100000, X < 16#10fffe -> + string(Rest, Handler, [?acc_seq(Acc, X)|Stack], Config); +string(<>, Handler, [Acc|Stack], Config) -> + case Config#config.replaced_bad_utf8 of + true -> noncharacter(<>, Handler, [Acc|Stack], Config) + ; false -> ?error([<>, Handler, [Acc|Stack], Config]) end; -string(Bin, Handler, Stack, Opts) -> +string(Bin, Handler, Stack, Config) -> case partial_utf(Bin) of - true -> ?incomplete(string, Bin, Handler, Stack, Opts) + true -> ?incomplete(string, Bin, Handler, Stack, Config) ; false -> - case Opts#opts.replaced_bad_utf8 of - true -> noncharacter(Bin, Handler, Stack, Opts) - ; false -> ?error([Bin, Handler, Stack, Opts]) + case Config#config.replaced_bad_utf8 of + true -> noncharacter(Bin, Handler, Stack, Config) + ; false -> ?error([Bin, Handler, Stack, Config]) end end. @@ -532,93 +532,93 @@ string(Bin, Handler, Stack, Opts) -> %% we don't need to guard against partial utf here, because it's already taken %% care of in string %% surrogates -noncharacter(<<237, X, _, Rest/binary>>, Handler, [Acc|Stack], Opts) when X >= 160 -> - string(Rest, Handler, [?acc_seq(Acc, 16#fffd)|Stack], Opts); +noncharacter(<<237, X, _, Rest/binary>>, Handler, [Acc|Stack], Config) when X >= 160 -> + string(Rest, Handler, [?acc_seq(Acc, 16#fffd)|Stack], Config); %% u+fffe and u+ffff for R14BXX -noncharacter(<<239, 191, X, Rest/binary>>, Handler, [Acc|Stack], Opts) when X == 190; X == 191 -> - string(Rest, Handler, [?acc_seq(Acc, 16#fffd)|Stack], Opts); +noncharacter(<<239, 191, X, Rest/binary>>, Handler, [Acc|Stack], Config) when X == 190; X == 191 -> + string(Rest, Handler, [?acc_seq(Acc, 16#fffd)|Stack], Config); %% u+xfffe, u+xffff and other noncharacters -noncharacter(<<_/utf8, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 16#fffd)|Stack], Opts); +noncharacter(<<_/utf8, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 16#fffd)|Stack], Config); %% overlong encodings and missing continuations of a 2 byte sequence -noncharacter(<>, Handler, Stack, Opts) when X >= 192, X =< 223 -> - strip_continuations(Rest, Handler, [1|Stack], Opts); +noncharacter(<>, Handler, Stack, Config) when X >= 192, X =< 223 -> + strip_continuations(Rest, Handler, [1|Stack], Config); %% overlong encodings and missing continuations of a 3 byte sequence -noncharacter(<>, Handler, Stack, Opts) when X >= 224, X =< 239 -> - strip_continuations(Rest, Handler, [2|Stack], Opts); +noncharacter(<>, Handler, Stack, Config) when X >= 224, X =< 239 -> + strip_continuations(Rest, Handler, [2|Stack], Config); %% overlong encodings and missing continuations of a 4 byte sequence -noncharacter(<>, Handler, Stack, Opts) when X >= 240, X =< 247 -> - strip_continuations(Rest, Handler, [3|Stack], Opts); +noncharacter(<>, Handler, Stack, Config) when X >= 240, X =< 247 -> + strip_continuations(Rest, Handler, [3|Stack], Config); %% unexpected bytes, including orphan continuations -noncharacter(<<_, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 16#fffd)|Stack], Opts); -noncharacter(<<>>, Handler, Stack, Opts) -> - ?incomplete(noncharacter, <<>>, Handler, Stack, Opts). +noncharacter(<<_, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 16#fffd)|Stack], Config); +noncharacter(<<>>, Handler, Stack, Config) -> + ?incomplete(noncharacter, <<>>, Handler, Stack, Config). %% strips continuation bytes after bad utf bytes, guards against both too short %% and overlong sequences. N is the maximum number of bytes to strip -strip_continuations(Rest, Handler, [0, Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 16#fffd)|Stack], Opts); -strip_continuations(<>, Handler, [N|Stack], Opts) when X >= 128, X =< 191 -> - strip_continuations(Rest, Handler, [N - 1|Stack], Opts); +strip_continuations(Rest, Handler, [0, Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 16#fffd)|Stack], Config); +strip_continuations(<>, Handler, [N|Stack], Config) when X >= 128, X =< 191 -> + strip_continuations(Rest, Handler, [N - 1|Stack], Config); %% incomplete -strip_continuations(<<>>, Handler, Stack, Opts) -> - ?incomplete(strip_continuations, <<>>, Handler, Stack, Opts); +strip_continuations(<<>>, Handler, Stack, Config) -> + ?incomplete(strip_continuations, <<>>, Handler, Stack, Config); %% not a continuation byte, dispatch back to string -strip_continuations(Rest, Handler, [_, Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, 16#fffd)|Stack], Opts). +strip_continuations(Rest, Handler, [_, Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, 16#fffd)|Stack], Config). -escape(<<$b, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, maybe_replace($\b, Opts))|Stack], Opts); -escape(<<$f, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, maybe_replace($\f, Opts))|Stack], Opts); -escape(<<$n, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, maybe_replace($\n, Opts))|Stack], Opts); -escape(<<$r, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, maybe_replace($\r, Opts))|Stack], Opts); -escape(<<$t, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, maybe_replace($\t, Opts))|Stack], Opts); -escape(<>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, maybe_replace($\\, Opts))|Stack], Opts); -escape(<>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, maybe_replace($/, Opts))|Stack], Opts); -escape(<>, Handler, [Acc|Stack], Opts) -> - string(Rest, Handler, [?acc_seq(Acc, maybe_replace($\", Opts))|Stack], Opts); -escape(<>, Handler, [Acc|Stack], Opts = #opts{single_quoted_strings=true}) -> - string(Rest, Handler, [?acc_seq(Acc, maybe_replace(?singlequote, Opts))|Stack], Opts); -escape(<<$u, Rest/binary>>, Handler, Stack, Opts) -> - escaped_unicode(Rest, Handler, Stack, Opts); -escape(<<>>, Handler, Stack, Opts) -> - ?incomplete(escape, <<>>, Handler, Stack, Opts); -escape(Bin, Handler, [Acc|Stack], Opts=#opts{ignored_bad_escapes=true}) -> - string(Bin, Handler, [?acc_seq(Acc, ?rsolidus)|Stack], Opts); -escape(Bin, Handler, Stack, Opts) -> - ?error([Bin, Handler, Stack, Opts]). +escape(<<$b, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, maybe_replace($\b, Config))|Stack], Config); +escape(<<$f, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, maybe_replace($\f, Config))|Stack], Config); +escape(<<$n, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, maybe_replace($\n, Config))|Stack], Config); +escape(<<$r, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, maybe_replace($\r, Config))|Stack], Config); +escape(<<$t, Rest/binary>>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, maybe_replace($\t, Config))|Stack], Config); +escape(<>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, maybe_replace($\\, Config))|Stack], Config); +escape(<>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, maybe_replace($/, Config))|Stack], Config); +escape(<>, Handler, [Acc|Stack], Config) -> + string(Rest, Handler, [?acc_seq(Acc, maybe_replace($\", Config))|Stack], Config); +escape(<>, Handler, [Acc|Stack], Config = #config{single_quoted_strings=true}) -> + string(Rest, Handler, [?acc_seq(Acc, maybe_replace(?singlequote, Config))|Stack], Config); +escape(<<$u, Rest/binary>>, Handler, Stack, Config) -> + escaped_unicode(Rest, Handler, Stack, Config); +escape(<<>>, Handler, Stack, Config) -> + ?incomplete(escape, <<>>, Handler, Stack, Config); +escape(Bin, Handler, [Acc|Stack], Config=#config{ignored_bad_escapes=true}) -> + string(Bin, Handler, [?acc_seq(Acc, ?rsolidus)|Stack], Config); +escape(Bin, Handler, Stack, Config) -> + ?error([Bin, Handler, Stack, Config]). %% this code is ugly and unfortunate, but so is json's handling of escaped %% unicode codepoint sequences. -escaped_unicode(<>, Handler, [Acc|Stack], Opts) +escaped_unicode(<>, Handler, [Acc|Stack], Config) when ?is_hex(A), ?is_hex(B), ?is_hex(C), ?is_hex(D) -> case erlang:list_to_integer([A, B, C, D], 16) of %% high surrogate, dispatch to low surrogate X when X >= 16#d800, X =< 16#dbff -> - low_surrogate(Rest, Handler, [X, Acc|Stack], Opts) + low_surrogate(Rest, Handler, [X, Acc|Stack], Config) %% low surrogate, illegal in this position ; X when X >= 16#dc00, X =< 16#dfff -> - case Opts#opts.replaced_bad_utf8 of - true -> string(Rest, Handler, [?acc_seq(Acc, 16#fffd)|Stack], Opts) - ; false -> ?error([<>, Handler, [Acc|Stack], Opts]) + case Config#config.replaced_bad_utf8 of + true -> string(Rest, Handler, [?acc_seq(Acc, 16#fffd)|Stack], Config) + ; false -> ?error([<>, Handler, [Acc|Stack], Config]) end %% anything else - ; X -> string(Rest, Handler, [?acc_seq(Acc, maybe_replace(X, Opts))|Stack], Opts) + ; X -> string(Rest, Handler, [?acc_seq(Acc, maybe_replace(X, Config))|Stack], Config) end; -escaped_unicode(Bin, Handler, Stack, Opts) -> +escaped_unicode(Bin, Handler, Stack, Config) -> case is_partial_escape(Bin) of - true -> ?incomplete(escaped_unicode, Bin, Handler, Stack, Opts) - ; false -> ?error([Bin, Handler, Stack, Opts]) + true -> ?incomplete(escaped_unicode, Bin, Handler, Stack, Config) + ; false -> ?error([Bin, Handler, Stack, Config]) end. @@ -629,34 +629,34 @@ is_partial_escape(<<>>) -> true; is_partial_escape(_) -> false. -low_surrogate(<>, Handler, [High, Acc|Stack], Opts) +low_surrogate(<>, Handler, [High, Acc|Stack], Config) when ?is_hex(A), ?is_hex(B), ?is_hex(C), ?is_hex(D) -> case erlang:list_to_integer([A, B, C, D], 16) of X when X >= 16#dc00, X =< 16#dfff -> Y = surrogate_to_codepoint(High, X), case (Y =< 16#d800 orelse Y >= 16#e000) of - true -> string(Rest, Handler, [?acc_seq(Acc, Y)|Stack], Opts) + true -> string(Rest, Handler, [?acc_seq(Acc, Y)|Stack], Config) ; false -> - case Opts#opts.replaced_bad_utf8 of + case Config#config.replaced_bad_utf8 of true -> - string(Rest, Handler, [?acc_seq(Acc, 16#fffd, 16#fffd)|Stack], Opts) + string(Rest, Handler, [?acc_seq(Acc, 16#fffd, 16#fffd)|Stack], Config) ; false -> - ?error([<>, Handler, [High, Acc|Stack], Opts]) + ?error([<>, Handler, [High, Acc|Stack], Config]) end end ; _ -> - case Opts#opts.replaced_bad_utf8 of - true -> string(Rest, Handler, [?acc_seq(Acc, 16#fffd, 16#fffd)|Stack], Opts) - ; false -> ?error([<>, Handler, [High, Acc|Stack], Opts]) + case Config#config.replaced_bad_utf8 of + true -> string(Rest, Handler, [?acc_seq(Acc, 16#fffd, 16#fffd)|Stack], Config) + ; false -> ?error([<>, Handler, [High, Acc|Stack], Config]) end end; -low_surrogate(Bin, Handler, [High, Acc|Stack], Opts) -> +low_surrogate(Bin, Handler, [High, Acc|Stack], Config) -> case is_partial_low(Bin) of - true -> ?incomplete(low_surrogate, Bin, Handler, [High, Acc|Stack], Opts) + true -> ?incomplete(low_surrogate, Bin, Handler, [High, Acc|Stack], Config) ; false -> - case Opts#opts.replaced_bad_utf8 of - true -> string(Bin, Handler, [?acc_seq(Acc, 16#fffd)|Stack], Opts) - ; false -> ?error([Bin, Handler, [High, Acc|Stack], Opts]) + case Config#config.replaced_bad_utf8 of + true -> string(Bin, Handler, [?acc_seq(Acc, 16#fffd)|Stack], Config) + ; false -> ?error([Bin, Handler, [High, Acc|Stack], Config]) end end. @@ -675,170 +675,170 @@ surrogate_to_codepoint(High, Low) -> (High - 16#d800) * 16#400 + (Low - 16#dc00) + 16#10000. -maybe_replace(X, #opts{dirty_strings=true}) when is_integer(X) -> [X]; -maybe_replace($\b, #opts{escaped_strings=true}) -> [$\\, $b]; -maybe_replace($\t, #opts{escaped_strings=true}) -> [$\\, $t]; -maybe_replace($\n, #opts{escaped_strings=true}) -> [$\\, $n]; -maybe_replace($\f, #opts{escaped_strings=true}) -> [$\\, $f]; -maybe_replace($\r, #opts{escaped_strings=true}) -> [$\\, $r]; -maybe_replace($\", #opts{escaped_strings=true}) -> [$\\, $\"]; -maybe_replace($', Opts=#opts{escaped_strings=true}) -> - case Opts#opts.single_quoted_strings of +maybe_replace(X, #config{dirty_strings=true}) when is_integer(X) -> [X]; +maybe_replace($\b, #config{escaped_strings=true}) -> [$\\, $b]; +maybe_replace($\t, #config{escaped_strings=true}) -> [$\\, $t]; +maybe_replace($\n, #config{escaped_strings=true}) -> [$\\, $n]; +maybe_replace($\f, #config{escaped_strings=true}) -> [$\\, $f]; +maybe_replace($\r, #config{escaped_strings=true}) -> [$\\, $r]; +maybe_replace($\", #config{escaped_strings=true}) -> [$\\, $\"]; +maybe_replace($', Config=#config{escaped_strings=true}) -> + case Config#config.single_quoted_strings of true -> [$\\, $'] ; false -> [$'] end; -maybe_replace($/, Opts=#opts{escaped_strings=true}) -> - case Opts#opts.escaped_forward_slashes of +maybe_replace($/, Config=#config{escaped_strings=true}) -> + case Config#config.escaped_forward_slashes of true -> [$\\, $/] ; false -> [$/] end; -maybe_replace($\\, #opts{escaped_strings=true}) -> [$\\, $\\]; -maybe_replace(X, Opts=#opts{escaped_strings=true}) when X == 16#2028; X == 16#2029 -> - case Opts#opts.unescaped_jsonp of +maybe_replace($\\, #config{escaped_strings=true}) -> [$\\, $\\]; +maybe_replace(X, Config=#config{escaped_strings=true}) when X == 16#2028; X == 16#2029 -> + case Config#config.unescaped_jsonp of true -> [X] ; false -> jsx_utils:json_escape_sequence(X) end; -maybe_replace(X, #opts{escaped_strings=true}) when X < 32 -> +maybe_replace(X, #config{escaped_strings=true}) when X < 32 -> jsx_utils:json_escape_sequence(X); -maybe_replace(X, _Opts) -> [X]. +maybe_replace(X, _Config) -> [X]. %% like strings, numbers are collected in an intermediate accumulator before %% being emitted to the callback handler -negative(<<$0, Rest/binary>>, Handler, [Acc|Stack], Opts) -> - zero(Rest, Handler, ["0" ++ Acc|Stack], Opts); -negative(<>, Handler, [Acc|Stack], Opts) when ?is_nonzero(S) -> - integer(Rest, Handler, [[S] ++ Acc|Stack], Opts); -negative(<<>>, Handler, Stack, Opts) -> - ?incomplete(negative, <<>>, Handler, Stack, Opts); -negative(Bin, Handler, Stack, Opts) -> - ?error([Bin, Handler, Stack, Opts]). +negative(<<$0, Rest/binary>>, Handler, [Acc|Stack], Config) -> + zero(Rest, Handler, ["0" ++ Acc|Stack], Config); +negative(<>, Handler, [Acc|Stack], Config) when ?is_nonzero(S) -> + integer(Rest, Handler, [[S] ++ Acc|Stack], Config); +negative(<<>>, Handler, Stack, Config) -> + ?incomplete(negative, <<>>, Handler, Stack, Config); +negative(Bin, Handler, Stack, Config) -> + ?error([Bin, Handler, Stack, Config]). -zero(<>, Handler, [Acc, object|Stack], Opts) -> - maybe_done(Rest, handle_event([format_number(Acc), end_object], Handler, Opts), Stack, Opts); -zero(<>, Handler, [Acc, array|Stack], Opts) -> - maybe_done(Rest, handle_event(end_array, handle_event(format_number(Acc), Handler, Opts), Opts), Stack, Opts); -zero(<>, Handler, [Acc, object|Stack], Opts) -> - key(Rest, handle_event(format_number(Acc), Handler, Opts), [key|Stack], Opts); -zero(<>, Handler, [Acc, array|Stack], Opts) -> - value(Rest, handle_event(format_number(Acc), Handler, Opts), [array|Stack], Opts); -zero(<>, Handler, [Acc|Stack], Opts) -> - initial_decimal(Rest, Handler, [{Acc, []}|Stack], Opts); -zero(<>, Handler, [Acc|Stack], Opts) when S =:= $e; S =:= $E -> - e(Rest, Handler, [{Acc, [], []}|Stack], Opts); -zero(<>, Handler, [Acc|Stack], Opts) when ?is_whitespace(S) -> - maybe_done(Rest, handle_event(format_number(Acc), Handler, Opts), Stack, Opts); -zero(<>, Handler, [Acc|Stack], Opts=#opts{comments=true}) -> - comment(Rest, handle_event(format_number(Acc), Handler, Opts), [maybe_done|Stack], Opts); -zero(<<>>, Handler, [Acc|[]], Opts = #opts{explicit_end=false}) -> - maybe_done(<<>>, handle_event(format_number(Acc), Handler, Opts), [], Opts); -zero(<<>>, Handler, Stack, Opts) -> - ?incomplete(zero, <<>>, Handler, Stack, Opts); -zero(Bin, Handler, Stack, Opts) -> - ?error([Bin, Handler, Stack, Opts]). +zero(<>, Handler, [Acc, object|Stack], Config) -> + maybe_done(Rest, handle_event([format_number(Acc), end_object], Handler, Config), Stack, Config); +zero(<>, Handler, [Acc, array|Stack], Config) -> + maybe_done(Rest, handle_event(end_array, handle_event(format_number(Acc), Handler, Config), Config), Stack, Config); +zero(<>, Handler, [Acc, object|Stack], Config) -> + key(Rest, handle_event(format_number(Acc), Handler, Config), [key|Stack], Config); +zero(<>, Handler, [Acc, array|Stack], Config) -> + value(Rest, handle_event(format_number(Acc), Handler, Config), [array|Stack], Config); +zero(<>, Handler, [Acc|Stack], Config) -> + initial_decimal(Rest, Handler, [{Acc, []}|Stack], Config); +zero(<>, Handler, [Acc|Stack], Config) when S =:= $e; S =:= $E -> + e(Rest, Handler, [{Acc, [], []}|Stack], Config); +zero(<>, Handler, [Acc|Stack], Config) when ?is_whitespace(S) -> + maybe_done(Rest, handle_event(format_number(Acc), Handler, Config), Stack, Config); +zero(<>, Handler, [Acc|Stack], Config=#config{comments=true}) -> + comment(Rest, handle_event(format_number(Acc), Handler, Config), [maybe_done|Stack], Config); +zero(<<>>, Handler, [Acc|[]], Config = #config{explicit_end=false}) -> + maybe_done(<<>>, handle_event(format_number(Acc), Handler, Config), [], Config); +zero(<<>>, Handler, Stack, Config) -> + ?incomplete(zero, <<>>, Handler, Stack, Config); +zero(Bin, Handler, Stack, Config) -> + ?error([Bin, Handler, Stack, Config]). -integer(<>, Handler, [Acc|Stack], Opts) when ?is_nonzero(S) -> - integer(Rest, Handler, [[S] ++ Acc|Stack], Opts); -integer(<>, Handler, [Acc, object|Stack], Opts) -> - maybe_done(Rest, handle_event([format_number(Acc), end_object], Handler, Opts), Stack, Opts); -integer(<>, Handler, [Acc, array|Stack], Opts) -> - maybe_done(Rest, handle_event([format_number(Acc), end_array], Handler, Opts), Stack, Opts); -integer(<>, Handler, [Acc, object|Stack], Opts) -> - key(Rest, handle_event(format_number(Acc), Handler, Opts), [key|Stack], Opts); -integer(<>, Handler, [Acc, array|Stack], Opts) -> - value(Rest, handle_event(format_number(Acc), Handler, Opts), [array|Stack], Opts); -integer(<>, Handler, [Acc|Stack], Opts) -> - initial_decimal(Rest, Handler, [{Acc, []}|Stack], Opts); -integer(<>, Handler, [Acc|Stack], Opts) -> - integer(Rest, Handler, [[?zero] ++ Acc|Stack], Opts); -integer(<>, Handler, [Acc|Stack], Opts) when S =:= $e; S =:= $E -> - e(Rest, Handler, [{Acc, [], []}|Stack], Opts); -integer(<>, Handler, [Acc|Stack], Opts) when ?is_whitespace(S) -> - maybe_done(Rest, handle_event(format_number(Acc), Handler, Opts), Stack, Opts); -integer(<>, Handler, [Acc|Stack], Opts=#opts{comments=true}) -> - comment(Rest, handle_event(format_number(Acc), Handler, Opts), [maybe_done|Stack], Opts); -integer(<<>>, Handler, [Acc|[]], Opts = #opts{explicit_end=false}) -> - maybe_done(<<>>, handle_event(format_number(Acc), Handler, Opts), [], Opts); -integer(<<>>, Handler, Stack, Opts) -> - ?incomplete(integer, <<>>, Handler, Stack, Opts); -integer(Bin, Handler, Stack, Opts) -> - ?error([Bin, Handler, Stack, Opts]). +integer(<>, Handler, [Acc|Stack], Config) when ?is_nonzero(S) -> + integer(Rest, Handler, [[S] ++ Acc|Stack], Config); +integer(<>, Handler, [Acc, object|Stack], Config) -> + maybe_done(Rest, handle_event([format_number(Acc), end_object], Handler, Config), Stack, Config); +integer(<>, Handler, [Acc, array|Stack], Config) -> + maybe_done(Rest, handle_event([format_number(Acc), end_array], Handler, Config), Stack, Config); +integer(<>, Handler, [Acc, object|Stack], Config) -> + key(Rest, handle_event(format_number(Acc), Handler, Config), [key|Stack], Config); +integer(<>, Handler, [Acc, array|Stack], Config) -> + value(Rest, handle_event(format_number(Acc), Handler, Config), [array|Stack], Config); +integer(<>, Handler, [Acc|Stack], Config) -> + initial_decimal(Rest, Handler, [{Acc, []}|Stack], Config); +integer(<>, Handler, [Acc|Stack], Config) -> + integer(Rest, Handler, [[?zero] ++ Acc|Stack], Config); +integer(<>, Handler, [Acc|Stack], Config) when S =:= $e; S =:= $E -> + e(Rest, Handler, [{Acc, [], []}|Stack], Config); +integer(<>, Handler, [Acc|Stack], Config) when ?is_whitespace(S) -> + maybe_done(Rest, handle_event(format_number(Acc), Handler, Config), Stack, Config); +integer(<>, Handler, [Acc|Stack], Config=#config{comments=true}) -> + comment(Rest, handle_event(format_number(Acc), Handler, Config), [maybe_done|Stack], Config); +integer(<<>>, Handler, [Acc|[]], Config = #config{explicit_end=false}) -> + maybe_done(<<>>, handle_event(format_number(Acc), Handler, Config), [], Config); +integer(<<>>, Handler, Stack, Config) -> + ?incomplete(integer, <<>>, Handler, Stack, Config); +integer(Bin, Handler, Stack, Config) -> + ?error([Bin, Handler, Stack, Config]). -initial_decimal(<>, Handler, [{Int, Frac}|Stack], Opts) when S =:= ?zero; ?is_nonzero(S) -> - decimal(Rest, Handler, [{Int, [S] ++ Frac}|Stack], Opts); -initial_decimal(<<>>, Handler, Stack, Opts) -> - ?incomplete(initial_decimal, <<>>, Handler, Stack, Opts); -initial_decimal(Bin, Handler, Stack, Opts) -> - ?error([Bin, Handler, Stack, Opts]). +initial_decimal(<>, Handler, [{Int, Frac}|Stack], Config) when S =:= ?zero; ?is_nonzero(S) -> + decimal(Rest, Handler, [{Int, [S] ++ Frac}|Stack], Config); +initial_decimal(<<>>, Handler, Stack, Config) -> + ?incomplete(initial_decimal, <<>>, Handler, Stack, Config); +initial_decimal(Bin, Handler, Stack, Config) -> + ?error([Bin, Handler, Stack, Config]). -decimal(<>, Handler, [{Int, Frac}|Stack], Opts) +decimal(<>, Handler, [{Int, Frac}|Stack], Config) when S=:= ?zero; ?is_nonzero(S) -> - decimal(Rest, Handler, [{Int, [S] ++ Frac}|Stack], Opts); -decimal(<>, Handler, [Acc, object|Stack], Opts) -> - maybe_done(Rest, handle_event([format_number(Acc), end_object], Handler, Opts), Stack, Opts); -decimal(<>, Handler, [Acc, array|Stack], Opts) -> - maybe_done(Rest, handle_event([format_number(Acc), end_array], Handler, Opts), Stack, Opts); -decimal(<>, Handler, [Acc, object|Stack], Opts) -> - key(Rest, handle_event(format_number(Acc), Handler, Opts), [key|Stack], Opts); -decimal(<>, Handler, [Acc, array|Stack], Opts) -> - value(Rest, handle_event(format_number(Acc), Handler, Opts), [array|Stack], Opts); -decimal(<>, Handler, [{Int, Frac}|Stack], Opts) when S =:= $e; S =:= $E -> - e(Rest, Handler, [{Int, Frac, []}|Stack], Opts); -decimal(<>, Handler, [Acc|Stack], Opts) when ?is_whitespace(S) -> - maybe_done(Rest, handle_event(format_number(Acc), Handler, Opts), Stack, Opts); -decimal(<>, Handler, [Acc|Stack], Opts=#opts{comments=true}) -> - comment(Rest, handle_event(format_number(Acc), Handler, Opts), [maybe_done|Stack], Opts); -decimal(<<>>, Handler, [Acc|[]], Opts = #opts{explicit_end=false}) -> - maybe_done(<<>>, handle_event(format_number(Acc), Handler, Opts), [], Opts); -decimal(<<>>, Handler, Stack, Opts) -> - ?incomplete(decimal, <<>>, Handler, Stack, Opts); -decimal(Bin, Handler, Stack, Opts) -> - ?error([Bin, Handler, Stack, Opts]). + decimal(Rest, Handler, [{Int, [S] ++ Frac}|Stack], Config); +decimal(<>, Handler, [Acc, object|Stack], Config) -> + maybe_done(Rest, handle_event([format_number(Acc), end_object], Handler, Config), Stack, Config); +decimal(<>, Handler, [Acc, array|Stack], Config) -> + maybe_done(Rest, handle_event([format_number(Acc), end_array], Handler, Config), Stack, Config); +decimal(<>, Handler, [Acc, object|Stack], Config) -> + key(Rest, handle_event(format_number(Acc), Handler, Config), [key|Stack], Config); +decimal(<>, Handler, [Acc, array|Stack], Config) -> + value(Rest, handle_event(format_number(Acc), Handler, Config), [array|Stack], Config); +decimal(<>, Handler, [{Int, Frac}|Stack], Config) when S =:= $e; S =:= $E -> + e(Rest, Handler, [{Int, Frac, []}|Stack], Config); +decimal(<>, Handler, [Acc|Stack], Config) when ?is_whitespace(S) -> + maybe_done(Rest, handle_event(format_number(Acc), Handler, Config), Stack, Config); +decimal(<>, Handler, [Acc|Stack], Config=#config{comments=true}) -> + comment(Rest, handle_event(format_number(Acc), Handler, Config), [maybe_done|Stack], Config); +decimal(<<>>, Handler, [Acc|[]], Config = #config{explicit_end=false}) -> + maybe_done(<<>>, handle_event(format_number(Acc), Handler, Config), [], Config); +decimal(<<>>, Handler, Stack, Config) -> + ?incomplete(decimal, <<>>, Handler, Stack, Config); +decimal(Bin, Handler, Stack, Config) -> + ?error([Bin, Handler, Stack, Config]). -e(<>, Handler, [{Int, Frac, Exp}|Stack], Opts) when S =:= ?zero; ?is_nonzero(S) -> - exp(Rest, Handler, [{Int, Frac, [S] ++ Exp}|Stack], Opts); -e(<>, Handler, [{Int, Frac, Exp}|Stack], Opts) when S =:= ?positive; S =:= ?negative -> - ex(Rest, Handler, [{Int, Frac, [S] ++ Exp}|Stack], Opts); -e(<<>>, Handler, Stack, Opts) -> - ?incomplete(e, <<>>, Handler, Stack, Opts); -e(Bin, Handler, Stack, Opts) -> - ?error([Bin, Handler, Stack, Opts]). +e(<>, Handler, [{Int, Frac, Exp}|Stack], Config) when S =:= ?zero; ?is_nonzero(S) -> + exp(Rest, Handler, [{Int, Frac, [S] ++ Exp}|Stack], Config); +e(<>, Handler, [{Int, Frac, Exp}|Stack], Config) when S =:= ?positive; S =:= ?negative -> + ex(Rest, Handler, [{Int, Frac, [S] ++ Exp}|Stack], Config); +e(<<>>, Handler, Stack, Config) -> + ?incomplete(e, <<>>, Handler, Stack, Config); +e(Bin, Handler, Stack, Config) -> + ?error([Bin, Handler, Stack, Config]). -ex(<>, Handler, [{Int, Frac, Exp}|Stack], Opts) when S =:= ?zero; ?is_nonzero(S) -> - exp(Rest, Handler, [{Int, Frac, [S] ++ Exp}|Stack], Opts); -ex(<<>>, Handler, Stack, Opts) -> - ?incomplete(ex, <<>>, Handler, Stack, Opts); -ex(Bin, Handler, Stack, Opts) -> - ?error([Bin, Handler, Stack, Opts]). +ex(<>, Handler, [{Int, Frac, Exp}|Stack], Config) when S =:= ?zero; ?is_nonzero(S) -> + exp(Rest, Handler, [{Int, Frac, [S] ++ Exp}|Stack], Config); +ex(<<>>, Handler, Stack, Config) -> + ?incomplete(ex, <<>>, Handler, Stack, Config); +ex(Bin, Handler, Stack, Config) -> + ?error([Bin, Handler, Stack, Config]). -exp(<>, Handler, [{Int, Frac, Exp}|Stack], Opts) when S =:= ?zero; ?is_nonzero(S) -> - exp(Rest, Handler, [{Int, Frac, [S] ++ Exp}|Stack], Opts); -exp(<>, Handler, [Acc, object|Stack], Opts) -> - maybe_done(Rest, handle_event([format_number(Acc), end_object], Handler, Opts), Stack, Opts); -exp(<>, Handler, [Acc, array|Stack], Opts) -> - maybe_done(Rest, handle_event([format_number(Acc), end_array], Handler, Opts), Stack, Opts); -exp(<>, Handler, [Acc, object|Stack], Opts) -> - key(Rest, handle_event(format_number(Acc), Handler, Opts), [key|Stack], Opts); -exp(<>, Handler, [Acc, array|Stack], Opts) -> - value(Rest, handle_event(format_number(Acc), Handler, Opts), [array|Stack], Opts); -exp(<>, Handler, [Acc|Stack], Opts) when ?is_whitespace(S) -> - maybe_done(Rest, handle_event(format_number(Acc), Handler, Opts), Stack, Opts); -exp(<>, Handler, [Acc|Stack], Opts=#opts{comments=true}) -> - comment(Rest, handle_event(format_number(Acc), Handler, Opts), [maybe_done|Stack], Opts); -exp(<<>>, Handler, [Acc|[]], Opts = #opts{explicit_end=false}) -> - maybe_done(<<>>, handle_event(format_number(Acc), Handler, Opts), [], Opts); -exp(<<>>, Handler, Stack, Opts) -> - ?incomplete(exp, <<>>, Handler, Stack, Opts); -exp(Bin, Handler, Stack, Opts) -> - ?error([Bin, Handler, Stack, Opts]). +exp(<>, Handler, [{Int, Frac, Exp}|Stack], Config) when S =:= ?zero; ?is_nonzero(S) -> + exp(Rest, Handler, [{Int, Frac, [S] ++ Exp}|Stack], Config); +exp(<>, Handler, [Acc, object|Stack], Config) -> + maybe_done(Rest, handle_event([format_number(Acc), end_object], Handler, Config), Stack, Config); +exp(<>, Handler, [Acc, array|Stack], Config) -> + maybe_done(Rest, handle_event([format_number(Acc), end_array], Handler, Config), Stack, Config); +exp(<>, Handler, [Acc, object|Stack], Config) -> + key(Rest, handle_event(format_number(Acc), Handler, Config), [key|Stack], Config); +exp(<>, Handler, [Acc, array|Stack], Config) -> + value(Rest, handle_event(format_number(Acc), Handler, Config), [array|Stack], Config); +exp(<>, Handler, [Acc|Stack], Config) when ?is_whitespace(S) -> + maybe_done(Rest, handle_event(format_number(Acc), Handler, Config), Stack, Config); +exp(<>, Handler, [Acc|Stack], Config=#config{comments=true}) -> + comment(Rest, handle_event(format_number(Acc), Handler, Config), [maybe_done|Stack], Config); +exp(<<>>, Handler, [Acc|[]], Config = #config{explicit_end=false}) -> + maybe_done(<<>>, handle_event(format_number(Acc), Handler, Config), [], Config); +exp(<<>>, Handler, Stack, Config) -> + ?incomplete(exp, <<>>, Handler, Stack, Config); +exp(Bin, Handler, Stack, Config) -> + ?error([Bin, Handler, Stack, Config]). format_number(Int) when is_list(Int) -> @@ -851,172 +851,172 @@ format_number({Int, Frac, Exp}) -> {float, list_to_float(lists:reverse(Exp ++ "e" ++ Frac ++ "." ++ Int))}. -tr(<<$r, Rest/binary>>, Handler, Stack, Opts) -> - tru(Rest, Handler, Stack, Opts); -tr(<<>>, Handler, Stack, Opts) -> - ?incomplete(tr, <<>>, Handler, Stack, Opts); -tr(Bin, Handler, Stack, Opts) -> - ?error([Bin, Handler, Stack, Opts]). +tr(<<$r, Rest/binary>>, Handler, Stack, Config) -> + tru(Rest, Handler, Stack, Config); +tr(<<>>, Handler, Stack, Config) -> + ?incomplete(tr, <<>>, Handler, Stack, Config); +tr(Bin, Handler, Stack, Config) -> + ?error([Bin, Handler, Stack, Config]). -tru(<<$u, Rest/binary>>, Handler, Stack, Opts) -> - true(Rest, Handler, Stack, Opts); -tru(<<>>, Handler, Stack, Opts) -> - ?incomplete(tru, <<>>, Handler, Stack, Opts); -tru(Bin, Handler, Stack, Opts) -> - ?error([Bin, Handler, Stack, Opts]). +tru(<<$u, Rest/binary>>, Handler, Stack, Config) -> + true(Rest, Handler, Stack, Config); +tru(<<>>, Handler, Stack, Config) -> + ?incomplete(tru, <<>>, Handler, Stack, Config); +tru(Bin, Handler, Stack, Config) -> + ?error([Bin, Handler, Stack, Config]). -true(<<$e, Rest/binary>>, Handler, Stack, Opts) -> - maybe_done(Rest, handle_event({literal, true}, Handler, Opts), Stack, Opts); -true(<<>>, Handler, Stack, Opts) -> - ?incomplete(true, <<>>, Handler, Stack, Opts); -true(Bin, Handler, Stack, Opts) -> - ?error([Bin, Handler, Stack, Opts]). +true(<<$e, Rest/binary>>, Handler, Stack, Config) -> + maybe_done(Rest, handle_event({literal, true}, Handler, Config), Stack, Config); +true(<<>>, Handler, Stack, Config) -> + ?incomplete(true, <<>>, Handler, Stack, Config); +true(Bin, Handler, Stack, Config) -> + ?error([Bin, Handler, Stack, Config]). -fa(<<$a, Rest/binary>>, Handler, Stack, Opts) -> - fal(Rest, Handler, Stack, Opts); -fa(<<>>, Handler, Stack, Opts) -> - ?incomplete(fa, <<>>, Handler, Stack, Opts); -fa(Bin, Handler, Stack, Opts) -> - ?error([Bin, Handler, Stack, Opts]). +fa(<<$a, Rest/binary>>, Handler, Stack, Config) -> + fal(Rest, Handler, Stack, Config); +fa(<<>>, Handler, Stack, Config) -> + ?incomplete(fa, <<>>, Handler, Stack, Config); +fa(Bin, Handler, Stack, Config) -> + ?error([Bin, Handler, Stack, Config]). -fal(<<$l, Rest/binary>>, Handler, Stack, Opts) -> - fals(Rest, Handler, Stack, Opts); -fal(<<>>, Handler, Stack, Opts) -> - ?incomplete(fal, <<>>, Handler, Stack, Opts); -fal(Bin, Handler, Stack, Opts) -> - ?error([Bin, Handler, Stack, Opts]). +fal(<<$l, Rest/binary>>, Handler, Stack, Config) -> + fals(Rest, Handler, Stack, Config); +fal(<<>>, Handler, Stack, Config) -> + ?incomplete(fal, <<>>, Handler, Stack, Config); +fal(Bin, Handler, Stack, Config) -> + ?error([Bin, Handler, Stack, Config]). -fals(<<$s, Rest/binary>>, Handler, Stack, Opts) -> - false(Rest, Handler, Stack, Opts); -fals(<<>>, Handler, Stack, Opts) -> - ?incomplete(fals, <<>>, Handler, Stack, Opts); -fals(Bin, Handler, Stack, Opts) -> - ?error([Bin, Handler, Stack, Opts]). +fals(<<$s, Rest/binary>>, Handler, Stack, Config) -> + false(Rest, Handler, Stack, Config); +fals(<<>>, Handler, Stack, Config) -> + ?incomplete(fals, <<>>, Handler, Stack, Config); +fals(Bin, Handler, Stack, Config) -> + ?error([Bin, Handler, Stack, Config]). -false(<<$e, Rest/binary>>, Handler, Stack, Opts) -> - maybe_done(Rest, handle_event({literal, false}, Handler, Opts), Stack, Opts); -false(<<>>, Handler, Stack, Opts) -> - ?incomplete(false, <<>>, Handler, Stack, Opts); -false(Bin, Handler, Stack, Opts) -> - ?error([Bin, Handler, Stack, Opts]). +false(<<$e, Rest/binary>>, Handler, Stack, Config) -> + maybe_done(Rest, handle_event({literal, false}, Handler, Config), Stack, Config); +false(<<>>, Handler, Stack, Config) -> + ?incomplete(false, <<>>, Handler, Stack, Config); +false(Bin, Handler, Stack, Config) -> + ?error([Bin, Handler, Stack, Config]). -nu(<<$u, Rest/binary>>, Handler, Stack, Opts) -> - nul(Rest, Handler, Stack, Opts); -nu(<<>>, Handler, Stack, Opts) -> - ?incomplete(nu, <<>>, Handler, Stack, Opts); -nu(Bin, Handler, Stack, Opts) -> - ?error([Bin, Handler, Stack, Opts]). +nu(<<$u, Rest/binary>>, Handler, Stack, Config) -> + nul(Rest, Handler, Stack, Config); +nu(<<>>, Handler, Stack, Config) -> + ?incomplete(nu, <<>>, Handler, Stack, Config); +nu(Bin, Handler, Stack, Config) -> + ?error([Bin, Handler, Stack, Config]). -nul(<<$l, Rest/binary>>, Handler, Stack, Opts) -> - null(Rest, Handler, Stack, Opts); -nul(<<>>, Handler, Stack, Opts) -> - ?incomplete(nul, <<>>, Handler, Stack, Opts); -nul(Bin, Handler, Stack, Opts) -> - ?error([Bin, Handler, Stack, Opts]). +nul(<<$l, Rest/binary>>, Handler, Stack, Config) -> + null(Rest, Handler, Stack, Config); +nul(<<>>, Handler, Stack, Config) -> + ?incomplete(nul, <<>>, Handler, Stack, Config); +nul(Bin, Handler, Stack, Config) -> + ?error([Bin, Handler, Stack, Config]). -null(<<$l, Rest/binary>>, Handler, Stack, Opts) -> - maybe_done(Rest, handle_event({literal, null}, Handler, Opts), Stack, Opts); -null(<<>>, Handler, Stack, Opts) -> - ?incomplete(null, <<>>, Handler, Stack, Opts); -null(Bin, Handler, Stack, Opts) -> - ?error([Bin, Handler, Stack, Opts]). +null(<<$l, Rest/binary>>, Handler, Stack, Config) -> + maybe_done(Rest, handle_event({literal, null}, Handler, Config), Stack, Config); +null(<<>>, Handler, Stack, Config) -> + ?incomplete(null, <<>>, Handler, Stack, Config); +null(Bin, Handler, Stack, Config) -> + ?error([Bin, Handler, Stack, Config]). -comment(<>, Handler, Stack, Opts) -> - single_comment(Rest, Handler, Stack, Opts); -comment(<>, Handler, Stack, Opts) -> - multi_comment(Rest, Handler, Stack, Opts); -comment(<<>>, Handler, Stack, Opts) -> - ?incomplete(comment, <<>>, Handler, Stack, Opts); -comment(Bin, Handler, Stack, Opts) -> - ?error([Bin, Handler, Stack, Opts]). +comment(<>, Handler, Stack, Config) -> + single_comment(Rest, Handler, Stack, Config); +comment(<>, Handler, Stack, Config) -> + multi_comment(Rest, Handler, Stack, Config); +comment(<<>>, Handler, Stack, Config) -> + ?incomplete(comment, <<>>, Handler, Stack, Config); +comment(Bin, Handler, Stack, Config) -> + ?error([Bin, Handler, Stack, Config]). -single_comment(<>, Handler, Stack, Opts) -> - end_comment(Rest, Handler, Stack, Opts); -single_comment(<<_/utf8, Rest/binary>>, Handler, Stack, Opts) -> - single_comment(Rest, Handler, Stack, Opts); -single_comment(<<>>, Handler, [done], Opts=#opts{explicit_end=false}) -> - end_comment(<<>>, Handler, [done], Opts); -single_comment(<<>>, Handler, Stack, Opts) -> - ?incomplete(single_comment, <<>>, Handler, Stack, Opts); -single_comment(Bin, Handler, Stack, Opts) -> - ?error([Bin, Handler, Stack, Opts]). +single_comment(<>, Handler, Stack, Config) -> + end_comment(Rest, Handler, Stack, Config); +single_comment(<<_/utf8, Rest/binary>>, Handler, Stack, Config) -> + single_comment(Rest, Handler, Stack, Config); +single_comment(<<>>, Handler, [done], Config=#config{explicit_end=false}) -> + end_comment(<<>>, Handler, [done], Config); +single_comment(<<>>, Handler, Stack, Config) -> + ?incomplete(single_comment, <<>>, Handler, Stack, Config); +single_comment(Bin, Handler, Stack, Config) -> + ?error([Bin, Handler, Stack, Config]). -multi_comment(<>, Handler, Stack, Opts) -> - end_multi_comment(Rest, Handler, Stack, Opts); -multi_comment(<<_S/utf8, Rest/binary>>, Handler, Stack, Opts) -> - multi_comment(Rest, Handler, Stack, Opts); -multi_comment(<<>>, Handler, Stack, Opts) -> - ?incomplete(multi_comment, <<>>, Handler, Stack, Opts); -multi_comment(Bin, Handler, Stack, Opts) -> - ?error([Bin, Handler, Stack, Opts]). +multi_comment(<>, Handler, Stack, Config) -> + end_multi_comment(Rest, Handler, Stack, Config); +multi_comment(<<_S/utf8, Rest/binary>>, Handler, Stack, Config) -> + multi_comment(Rest, Handler, Stack, Config); +multi_comment(<<>>, Handler, Stack, Config) -> + ?incomplete(multi_comment, <<>>, Handler, Stack, Config); +multi_comment(Bin, Handler, Stack, Config) -> + ?error([Bin, Handler, Stack, Config]). -end_multi_comment(<>, Handler, Stack, Opts) -> - end_comment(Rest, Handler, Stack, Opts); -end_multi_comment(<<_S/utf8, Rest/binary>>, Handler, Stack, Opts) -> - multi_comment(Rest, Handler, Stack, Opts); -end_multi_comment(<<>>, Handler, Stack, Opts) -> - ?incomplete(end_multi_comment, <<>>, Handler, Stack, Opts); -end_multi_comment(Bin, Handler, Stack, Opts) -> - ?error([Bin, Handler, Stack, Opts]). +end_multi_comment(<>, Handler, Stack, Config) -> + end_comment(Rest, Handler, Stack, Config); +end_multi_comment(<<_S/utf8, Rest/binary>>, Handler, Stack, Config) -> + multi_comment(Rest, Handler, Stack, Config); +end_multi_comment(<<>>, Handler, Stack, Config) -> + ?incomplete(end_multi_comment, <<>>, Handler, Stack, Config); +end_multi_comment(Bin, Handler, Stack, Config) -> + ?error([Bin, Handler, Stack, Config]). -end_comment(Rest, Handler, [Resume|Stack], Opts) -> +end_comment(Rest, Handler, [Resume|Stack], Config) -> case Resume of - value -> value(Rest, Handler, Stack, Opts) - ; object -> object(Rest, Handler, Stack, Opts) - ; array -> array(Rest, Handler, Stack, Opts) - ; colon -> colon(Rest, Handler, Stack, Opts) - ; key -> key(Rest, Handler, Stack, Opts) - ; maybe_done -> maybe_done(Rest, Handler, Stack, Opts) - ; done -> done(Rest, Handler, Stack, Opts) + value -> value(Rest, Handler, Stack, Config) + ; object -> object(Rest, Handler, Stack, Config) + ; array -> array(Rest, Handler, Stack, Config) + ; colon -> colon(Rest, Handler, Stack, Config) + ; key -> key(Rest, Handler, Stack, Config) + ; maybe_done -> maybe_done(Rest, Handler, Stack, Config) + ; done -> done(Rest, Handler, Stack, Config) end. -maybe_done(Rest, Handler, [], Opts) -> - done(Rest, handle_event(end_json, Handler, Opts), [], Opts); -maybe_done(<>, Handler, [object|Stack], Opts) -> - maybe_done(Rest, handle_event(end_object, Handler, Opts), Stack, Opts); -maybe_done(<>, Handler, [array|Stack], Opts) -> - maybe_done(Rest, handle_event(end_array, Handler, Opts), Stack, Opts); -maybe_done(<>, Handler, [object|Stack], Opts) -> - key(Rest, Handler, [key|Stack], Opts); -maybe_done(<>, Handler, [array|_] = Stack, Opts) -> - value(Rest, Handler, Stack, Opts); -maybe_done(<>, Handler, Stack, Opts) when ?is_whitespace(S) -> - maybe_done(Rest, Handler, Stack, Opts); -maybe_done(<>, Handler, Stack, Opts=#opts{comments=true}) -> - comment(Rest, Handler, [maybe_done|Stack], Opts); -maybe_done(<<>>, Handler, Stack, Opts) when length(Stack) > 0 -> - ?incomplete(maybe_done, <<>>, Handler, Stack, Opts); -maybe_done(Bin, Handler, Stack, Opts) -> - ?error([Bin, Handler, Stack, Opts]). +maybe_done(Rest, Handler, [], Config) -> + done(Rest, handle_event(end_json, Handler, Config), [], Config); +maybe_done(<>, Handler, [object|Stack], Config) -> + maybe_done(Rest, handle_event(end_object, Handler, Config), Stack, Config); +maybe_done(<>, Handler, [array|Stack], Config) -> + maybe_done(Rest, handle_event(end_array, Handler, Config), Stack, Config); +maybe_done(<>, Handler, [object|Stack], Config) -> + key(Rest, Handler, [key|Stack], Config); +maybe_done(<>, Handler, [array|_] = Stack, Config) -> + value(Rest, Handler, Stack, Config); +maybe_done(<>, Handler, Stack, Config) when ?is_whitespace(S) -> + maybe_done(Rest, Handler, Stack, Config); +maybe_done(<>, Handler, Stack, Config=#config{comments=true}) -> + comment(Rest, Handler, [maybe_done|Stack], Config); +maybe_done(<<>>, Handler, Stack, Config) when length(Stack) > 0 -> + ?incomplete(maybe_done, <<>>, Handler, Stack, Config); +maybe_done(Bin, Handler, Stack, Config) -> + ?error([Bin, Handler, Stack, Config]). -done(<>, Handler, [], Opts) when ?is_whitespace(S) -> - done(Rest, Handler, [], Opts); -done(<>, Handler, [], Opts=#opts{comments=true}) -> - comment(Rest, Handler, [done], Opts); -done(<<>>, {Handler, State}, [], Opts = #opts{explicit_end=true}) -> +done(<>, Handler, [], Config) when ?is_whitespace(S) -> + done(Rest, Handler, [], Config); +done(<>, Handler, [], Config=#config{comments=true}) -> + comment(Rest, Handler, [done], Config); +done(<<>>, {Handler, State}, [], Config = #config{explicit_end=true}) -> {incomplete, fun(Stream) when is_binary(Stream) -> - done(<>, {Handler, State}, [], Opts) + done(<>, {Handler, State}, [], Config) ; (end_stream) -> State end }; -done(<<>>, {_Handler, State}, [], _Opts) -> State; -done(Bin, Handler, Stack, Opts) -> ?error([Bin, Handler, Stack, Opts]). +done(<<>>, {_Handler, State}, [], _Config) -> State; +done(Bin, Handler, Stack, Config) -> ?error([Bin, Handler, Stack, Config]). @@ -1026,9 +1026,9 @@ done(Bin, Handler, Stack, Opts) -> ?error([Bin, Handler, Stack, Opts]). xcode(Bin) -> xcode(Bin, []). -xcode(Bin, Opts) -> +xcode(Bin, Config) -> Size = size(Bin), - try jsx:to_term(<<34, Bin:Size/binary, 34>>, Opts) + try jsx:to_term(<<34, Bin:Size/binary, 34>>, Config) catch error:badarg -> {error, badarg} end. @@ -1225,9 +1225,9 @@ bad_utf8_test_() -> ]. -decode(JSON, Opts) -> +decode(JSON, Config) -> try - (decoder(jsx, [], Opts))(JSON) + (decoder(jsx, [], Config))(JSON) catch error:badarg -> {error, badarg} end. @@ -1551,16 +1551,16 @@ check_replaced(List) -> check_good(List) -> check_good(List, []). -check_good(List, Opts) -> +check_good(List, Config) -> [] == lists:dropwhile(fun({_, [{string, _}|_]}) -> true ; (_) -> false end, - check(List, Opts, []) + check(List, Config, []) ). -check([], _Opts, Acc) -> Acc; -check([H|T], Opts, Acc) -> - R = decode(to_fake_utf(H, utf8), Opts), - check(T, Opts, [{H, R}] ++ Acc). +check([], _Config, Acc) -> Acc; +check([H|T], Config, Acc) -> + R = decode(to_fake_utf(H, utf8), Config), + check(T, Config, [{H, R}] ++ Acc). noncharacters() -> lists:seq(16#fffe, 16#ffff). @@ -1619,7 +1619,7 @@ decode_test_() -> { Title, ?_assertEqual( Events ++ [end_json], - start(JSON, {jsx, []}, [], #opts{}) + start(JSON, {jsx, []}, [], #config{}) ) } || {Title, JSON, _, Events} <- Data ]. diff --git a/src/jsx_encoder.erl b/src/jsx_encoder.erl index ac2a72d..3d7f78d 100644 --- a/src/jsx_encoder.erl +++ b/src/jsx_encoder.erl @@ -25,20 +25,20 @@ -export([encoder/3, pre_encode/2]). --spec encoder(Handler::module(), State::any(), Opts::jsx:opts()) -> jsx:encoder(). +-spec encoder(Handler::module(), State::any(), Config::jsx:config()) -> jsx:encoder(). -encoder(Handler, State, Opts) -> +encoder(Handler, State, Config) -> fun(JSON) -> start( JSON, {Handler, Handler:init(State)}, - jsx_utils:parse_opts(Opts) + jsx_utils:parse_config(Config) ) end. --include("jsx_opts.hrl"). +-include("jsx_config.hrl"). -ifndef(error). @@ -48,87 +48,87 @@ encoder(Handler, State, Opts) -> -endif. -start(Term, {Handler, State}, Opts) -> - Handler:handle_event(end_json, value(pre_encode(Term, Opts), {Handler, State}, Opts)). +start(Term, {Handler, State}, Config) -> + Handler:handle_event(end_json, value(pre_encode(Term, Config), {Handler, State}, Config)). -value(String, {Handler, State}, Opts) when is_binary(String) -> - Handler:handle_event({string, clean_string(String, Opts)}, State); -value(Float, {Handler, State}, _Opts) when is_float(Float) -> +value(String, {Handler, State}, Config) when is_binary(String) -> + Handler:handle_event({string, clean_string(String, Config)}, State); +value(Float, {Handler, State}, _Config) when is_float(Float) -> Handler:handle_event({float, Float}, State); -value(Int, {Handler, State}, _Opts) when is_integer(Int) -> +value(Int, {Handler, State}, _Config) when is_integer(Int) -> Handler:handle_event({integer, Int}, State); -value(Literal, {Handler, State}, _Opts) +value(Literal, {Handler, State}, _Config) when Literal == true; Literal == false; Literal == null -> Handler:handle_event({literal, Literal}, State); -value([{}], {Handler, State}, _Opts) -> +value([{}], {Handler, State}, _Config) -> Handler:handle_event(end_object, Handler:handle_event(start_object, State)); -value([], {Handler, State}, _Opts) -> +value([], {Handler, State}, _Config) -> Handler:handle_event(end_array, Handler:handle_event(start_array, State)); -value([Tuple|_] = List, Handler, Opts) when is_tuple(Tuple) -> - list_or_object(List, Handler, Opts); -value(List, Handler, Opts) when is_list(List) -> - list_or_object(List, Handler, Opts); -value(Term, Handler, Opts) -> ?error([Term, Handler, Opts]). +value([Tuple|_] = List, Handler, Config) when is_tuple(Tuple) -> + list_or_object(List, Handler, Config); +value(List, Handler, Config) when is_list(List) -> + list_or_object(List, Handler, Config); +value(Term, Handler, Config) -> ?error([Term, Handler, Config]). -list_or_object([Term|Rest], {Handler, State}, Opts) -> - case pre_encode(Term, Opts) of +list_or_object([Term|Rest], {Handler, State}, Config) -> + case pre_encode(Term, Config) of {K, V} -> - object([{K, V}|Rest], {Handler, Handler:handle_event(start_object, State)}, Opts) + object([{K, V}|Rest], {Handler, Handler:handle_event(start_object, State)}, Config) ; T -> - list([T|Rest], {Handler, Handler:handle_event(start_array, State)}, Opts) + list([T|Rest], {Handler, Handler:handle_event(start_array, State)}, Config) end. -object([{Key, Value}, Next|Rest], {Handler, State}, Opts) when is_atom(Key); is_binary(Key) -> - V = pre_encode(Value, Opts), +object([{Key, Value}, Next|Rest], {Handler, State}, Config) when is_atom(Key); is_binary(Key) -> + V = pre_encode(Value, Config), object( - [pre_encode(Next, Opts)|Rest], + [pre_encode(Next, Config)|Rest], { Handler, value( V, - {Handler, Handler:handle_event({key, clean_string(fix_key(Key), Opts)}, State)}, - Opts + {Handler, Handler:handle_event({key, clean_string(fix_key(Key), Config)}, State)}, + Config ) }, - Opts + Config ); -object([{Key, Value}], {Handler, State}, Opts) when is_atom(Key); is_binary(Key) -> +object([{Key, Value}], {Handler, State}, Config) when is_atom(Key); is_binary(Key) -> object( [], { Handler, value( - pre_encode(Value, Opts), - {Handler, Handler:handle_event({key, clean_string(fix_key(Key), Opts)}, State)}, - Opts + pre_encode(Value, Config), + {Handler, Handler:handle_event({key, clean_string(fix_key(Key), Config)}, State)}, + Config ) }, - Opts + Config ); -object([], {Handler, State}, _Opts) -> Handler:handle_event(end_object, State); -object(Term, Handler, Opts) -> ?error([Term, Handler, Opts]). +object([], {Handler, State}, _Config) -> Handler:handle_event(end_object, State); +object(Term, Handler, Config) -> ?error([Term, Handler, Config]). -list([Value, Next|Rest], {Handler, State}, Opts) -> - list([pre_encode(Next, Opts)|Rest], {Handler, value(Value, {Handler, State}, Opts)}, Opts); -list([Value], {Handler, State}, Opts) -> - list([], {Handler, value(Value, {Handler, State}, Opts)}, Opts); -list([], {Handler, State}, _Opts) -> Handler:handle_event(end_array, State); -list(Term, Handler, Opts) -> ?error([Term, Handler, Opts]). +list([Value, Next|Rest], {Handler, State}, Config) -> + list([pre_encode(Next, Config)|Rest], {Handler, value(Value, {Handler, State}, Config)}, Config); +list([Value], {Handler, State}, Config) -> + list([], {Handler, value(Value, {Handler, State}, Config)}, Config); +list([], {Handler, State}, _Config) -> Handler:handle_event(end_array, State); +list(Term, Handler, Config) -> ?error([Term, Handler, Config]). -pre_encode(Value, #opts{pre_encode=false}) -> io:format("~p~n", [Value]), Value; -pre_encode(Value, Opts) -> (Opts#opts.pre_encode)(Value). +pre_encode(Value, #config{pre_encode=false}) -> io:format("~p~n", [Value]), Value; +pre_encode(Value, Config) -> (Config#config.pre_encode)(Value). fix_key(Key) when is_atom(Key) -> fix_key(atom_to_binary(Key, utf8)); fix_key(Key) when is_binary(Key) -> Key. -clean_string(Bin, Opts) -> jsx_utils:clean_string(Bin, Opts). +clean_string(Bin, Config) -> jsx_utils:clean_string(Bin, Config). @@ -142,7 +142,7 @@ encode_test_() -> { Title, ?_assertEqual( Events ++ [end_json], - start(Term, {jsx, []}, #opts{}) + start(Term, {jsx, []}, #config{}) ) } || {Title, _, Term, Events} <- Data ]. diff --git a/src/jsx_parser.erl b/src/jsx_parser.erl index c67eefd..f5030be 100644 --- a/src/jsx_parser.erl +++ b/src/jsx_parser.erl @@ -26,13 +26,13 @@ -export([parser/3]). --spec parser(Handler::module(), State::any(), Opts::jsx:opts()) -> jsx:parser(). +-spec parser(Handler::module(), State::any(), Config::jsx:config()) -> jsx:parser(). -parser(Handler, State, Opts) -> - fun(Tokens) -> value(Tokens, {Handler, Handler:init(State)}, [], jsx_utils:parse_opts(Opts)) end. +parser(Handler, State, Config) -> + fun(Tokens) -> value(Tokens, {Handler, Handler:init(State)}, [], jsx_utils:parse_config(Config)) end. --include("jsx_opts.hrl"). +-include("jsx_config.hrl"). %% error, incomplete and event macros @@ -44,124 +44,124 @@ parser(Handler, State, Opts) -> -ifndef(incomplete). --define(incomplete(State, Handler, Stack, Opts), +-define(incomplete(State, Handler, Stack, Config), {incomplete, fun(end_stream) -> case State([end_json], Handler, Stack, - Opts) of - {incomplete, _} -> ?error([Handler, Stack, Opts]) + Config) of + {incomplete, _} -> ?error([Handler, Stack, Config]) ; Events -> Events end ; (Tokens) -> - State(Tokens, Handler, Stack, Opts) + State(Tokens, Handler, Stack, Config) end } ). -endif. -handle_event([], Handler, _Opts) -> Handler; -handle_event([Event|Rest], Handler, Opts) -> handle_event(Rest, handle_event(Event, Handler, Opts), Opts); -handle_event(Event, {Handler, State}, _Opts) -> {Handler, Handler:handle_event(Event, State)}. +handle_event([], Handler, _Config) -> Handler; +handle_event([Event|Rest], Handler, Config) -> handle_event(Rest, handle_event(Event, Handler, Config), Config); +handle_event(Event, {Handler, State}, _Config) -> {Handler, Handler:handle_event(Event, State)}. -value([start_object|Tokens], Handler, Stack, Opts) -> - object(Tokens, handle_event(start_object, Handler, Opts), [object|Stack], Opts); -value([start_array|Tokens], Handler, Stack, Opts) -> - array(Tokens, handle_event(start_array, Handler, Opts), [array|Stack], Opts); -value([{literal, true}|Tokens], Handler, [], Opts) -> - done(Tokens, handle_event({literal, true}, Handler, Opts), [], Opts); -value([{literal, false}|Tokens], Handler, [], Opts) -> - done(Tokens, handle_event({literal, false}, Handler, Opts), [], Opts); -value([{literal, null}|Tokens], Handler, [], Opts) -> - done(Tokens, handle_event({literal, null}, Handler, Opts), [], Opts); -value([{literal, true}|Tokens], Handler, Stack, Opts) -> - maybe_done(Tokens, handle_event({literal, true}, Handler, Opts), Stack, Opts); -value([{literal, false}|Tokens], Handler, Stack, Opts) -> - maybe_done(Tokens, handle_event({literal, false}, Handler, Opts), Stack, Opts); -value([{literal, null}|Tokens], Handler, Stack, Opts) -> - maybe_done(Tokens, handle_event({literal, null}, Handler, Opts), Stack, Opts); -value([Literal|Tokens], Handler, Stack, Opts) when Literal == true; Literal == false; Literal == null -> - value([{literal, Literal}] ++ Tokens, Handler, Stack, Opts); -value([{integer, Number}|Tokens], Handler, [], Opts) when is_integer(Number) -> - done(Tokens, handle_event({integer, Number}, Handler, Opts), [], Opts); -value([{float, Number}|Tokens], Handler, [], Opts) when is_float(Number) -> - done(Tokens, handle_event({float, Number}, Handler, Opts), [], Opts); -value([{integer, Number}|Tokens], Handler, Stack, Opts) when is_integer(Number) -> - maybe_done(Tokens, handle_event({integer, Number}, Handler, Opts), Stack, Opts); -value([{float, Number}|Tokens], Handler, Stack, Opts) when is_float(Number) -> - maybe_done(Tokens, handle_event({float, Number}, Handler, Opts), Stack, Opts); -value([{number, Number}|Tokens], Handler, Stack, Opts) when is_integer(Number) -> - value([{integer, Number}] ++ Tokens, Handler, Stack, Opts); -value([{number, Number}|Tokens], Handler, Stack, Opts) when is_float(Number) -> - value([{float, Number}] ++ Tokens, Handler, Stack, Opts); -value([Number|Tokens], Handler, Stack, Opts) when is_integer(Number) -> - value([{integer, Number}] ++ Tokens, Handler, Stack, Opts); -value([Number|Tokens], Handler, Stack, Opts) when is_float(Number) -> - value([{float, Number}] ++ Tokens, Handler, Stack, Opts); -value([{string, String}|Tokens], Handler, [], Opts) when is_binary(String) -> - done(Tokens, handle_event({string, clean_string(String, Opts)}, Handler, Opts), [], Opts); -value([{string, String}|Tokens], Handler, Stack, Opts) when is_binary(String) -> - maybe_done(Tokens, handle_event({string, clean_string(String, Opts)}, Handler, Opts), Stack, Opts); -value([String|Tokens], Handler, Stack, Opts) when is_binary(String) -> - value([{string, String}] ++ Tokens, Handler, Stack, Opts); -value([], Handler, Stack, Opts) -> - ?incomplete(value, Handler, Stack, Opts); -value(BadTokens, Handler, Stack, Opts) when is_list(BadTokens) -> - ?error([BadTokens, Handler, Stack, Opts]); -value(Token, Handler, Stack, Opts) -> - value([Token], Handler, Stack, Opts). +value([start_object|Tokens], Handler, Stack, Config) -> + object(Tokens, handle_event(start_object, Handler, Config), [object|Stack], Config); +value([start_array|Tokens], Handler, Stack, Config) -> + array(Tokens, handle_event(start_array, Handler, Config), [array|Stack], Config); +value([{literal, true}|Tokens], Handler, [], Config) -> + done(Tokens, handle_event({literal, true}, Handler, Config), [], Config); +value([{literal, false}|Tokens], Handler, [], Config) -> + done(Tokens, handle_event({literal, false}, Handler, Config), [], Config); +value([{literal, null}|Tokens], Handler, [], Config) -> + done(Tokens, handle_event({literal, null}, Handler, Config), [], Config); +value([{literal, true}|Tokens], Handler, Stack, Config) -> + maybe_done(Tokens, handle_event({literal, true}, Handler, Config), Stack, Config); +value([{literal, false}|Tokens], Handler, Stack, Config) -> + maybe_done(Tokens, handle_event({literal, false}, Handler, Config), Stack, Config); +value([{literal, null}|Tokens], Handler, Stack, Config) -> + maybe_done(Tokens, handle_event({literal, null}, Handler, Config), Stack, Config); +value([Literal|Tokens], Handler, Stack, Config) when Literal == true; Literal == false; Literal == null -> + value([{literal, Literal}] ++ Tokens, Handler, Stack, Config); +value([{integer, Number}|Tokens], Handler, [], Config) when is_integer(Number) -> + done(Tokens, handle_event({integer, Number}, Handler, Config), [], Config); +value([{float, Number}|Tokens], Handler, [], Config) when is_float(Number) -> + done(Tokens, handle_event({float, Number}, Handler, Config), [], Config); +value([{integer, Number}|Tokens], Handler, Stack, Config) when is_integer(Number) -> + maybe_done(Tokens, handle_event({integer, Number}, Handler, Config), Stack, Config); +value([{float, Number}|Tokens], Handler, Stack, Config) when is_float(Number) -> + maybe_done(Tokens, handle_event({float, Number}, Handler, Config), Stack, Config); +value([{number, Number}|Tokens], Handler, Stack, Config) when is_integer(Number) -> + value([{integer, Number}] ++ Tokens, Handler, Stack, Config); +value([{number, Number}|Tokens], Handler, Stack, Config) when is_float(Number) -> + value([{float, Number}] ++ Tokens, Handler, Stack, Config); +value([Number|Tokens], Handler, Stack, Config) when is_integer(Number) -> + value([{integer, Number}] ++ Tokens, Handler, Stack, Config); +value([Number|Tokens], Handler, Stack, Config) when is_float(Number) -> + value([{float, Number}] ++ Tokens, Handler, Stack, Config); +value([{string, String}|Tokens], Handler, [], Config) when is_binary(String) -> + done(Tokens, handle_event({string, clean_string(String, Config)}, Handler, Config), [], Config); +value([{string, String}|Tokens], Handler, Stack, Config) when is_binary(String) -> + maybe_done(Tokens, handle_event({string, clean_string(String, Config)}, Handler, Config), Stack, Config); +value([String|Tokens], Handler, Stack, Config) when is_binary(String) -> + value([{string, String}] ++ Tokens, Handler, Stack, Config); +value([], Handler, Stack, Config) -> + ?incomplete(value, Handler, Stack, Config); +value(BadTokens, Handler, Stack, Config) when is_list(BadTokens) -> + ?error([BadTokens, Handler, Stack, Config]); +value(Token, Handler, Stack, Config) -> + value([Token], Handler, Stack, Config). -object([end_object|Tokens], Handler, [object|Stack], Opts) -> - maybe_done(Tokens, handle_event(end_object, Handler, Opts), Stack, Opts); -object([{key, Key}|Tokens], Handler, Stack, Opts) when is_atom(Key); is_binary(Key) -> - value(Tokens, handle_event({key, clean_string(fix_key(Key), Opts)}, Handler, Opts), Stack, Opts); -object([Key|Tokens], Handler, Stack, Opts) when is_atom(Key); is_binary(Key) -> - value(Tokens, handle_event({key, clean_string(fix_key(Key), Opts)}, Handler, Opts), Stack, Opts); -object([], Handler, Stack, Opts) -> - ?incomplete(object, Handler, Stack, Opts); -object(BadTokens, Handler, Stack, Opts) when is_list(BadTokens) -> - ?error([BadTokens, Handler, Stack, Opts]); -object(Token, Handler, Stack, Opts) -> - object([Token], Handler, Stack, Opts). +object([end_object|Tokens], Handler, [object|Stack], Config) -> + maybe_done(Tokens, handle_event(end_object, Handler, Config), Stack, Config); +object([{key, Key}|Tokens], Handler, Stack, Config) when is_atom(Key); is_binary(Key) -> + value(Tokens, handle_event({key, clean_string(fix_key(Key), Config)}, Handler, Config), Stack, Config); +object([Key|Tokens], Handler, Stack, Config) when is_atom(Key); is_binary(Key) -> + value(Tokens, handle_event({key, clean_string(fix_key(Key), Config)}, Handler, Config), Stack, Config); +object([], Handler, Stack, Config) -> + ?incomplete(object, Handler, Stack, Config); +object(BadTokens, Handler, Stack, Config) when is_list(BadTokens) -> + ?error([BadTokens, Handler, Stack, Config]); +object(Token, Handler, Stack, Config) -> + object([Token], Handler, Stack, Config). -array([end_array|Tokens], Handler, [array|Stack], Opts) -> - maybe_done(Tokens, handle_event(end_array, Handler, Opts), Stack, Opts); -array([], Handler, Stack, Opts) -> - ?incomplete(array, Handler, Stack, Opts); -array(Tokens, Handler, Stack, Opts) when is_list(Tokens) -> - value(Tokens, Handler, Stack, Opts); -array(Token, Handler, Stack, Opts) -> - array([Token], Handler, Stack, Opts). +array([end_array|Tokens], Handler, [array|Stack], Config) -> + maybe_done(Tokens, handle_event(end_array, Handler, Config), Stack, Config); +array([], Handler, Stack, Config) -> + ?incomplete(array, Handler, Stack, Config); +array(Tokens, Handler, Stack, Config) when is_list(Tokens) -> + value(Tokens, Handler, Stack, Config); +array(Token, Handler, Stack, Config) -> + array([Token], Handler, Stack, Config). -maybe_done([end_json], Handler, [], Opts) -> - done([], Handler, [], Opts); -maybe_done(Tokens, Handler, [object|_] = Stack, Opts) when is_list(Tokens) -> - object(Tokens, Handler, Stack, Opts); -maybe_done(Tokens, Handler, [array|_] = Stack, Opts) when is_list(Tokens) -> - array(Tokens, Handler, Stack, Opts); -maybe_done([], Handler, Stack, Opts) -> - ?incomplete(maybe_done, Handler, Stack, Opts); -maybe_done(BadTokens, Handler, Stack, Opts) when is_list(BadTokens) -> - ?error([BadTokens, Handler, Stack, Opts]); -maybe_done(Token, Handler, Stack, Opts) -> - maybe_done([Token], Handler, Stack, Opts). +maybe_done([end_json], Handler, [], Config) -> + done([], Handler, [], Config); +maybe_done(Tokens, Handler, [object|_] = Stack, Config) when is_list(Tokens) -> + object(Tokens, Handler, Stack, Config); +maybe_done(Tokens, Handler, [array|_] = Stack, Config) when is_list(Tokens) -> + array(Tokens, Handler, Stack, Config); +maybe_done([], Handler, Stack, Config) -> + ?incomplete(maybe_done, Handler, Stack, Config); +maybe_done(BadTokens, Handler, Stack, Config) when is_list(BadTokens) -> + ?error([BadTokens, Handler, Stack, Config]); +maybe_done(Token, Handler, Stack, Config) -> + maybe_done([Token], Handler, Stack, Config). -done(Tokens, Handler, [], Opts) when Tokens == [end_json]; Tokens == [] -> - {_, State} = handle_event(end_json, Handler, Opts), +done(Tokens, Handler, [], Config) when Tokens == [end_json]; Tokens == [] -> + {_, State} = handle_event(end_json, Handler, Config), State; -done(BadTokens, Handler, Stack, Opts) when is_list(BadTokens) -> - ?error([BadTokens, Handler, Stack, Opts]); -done(Token, Handler, Stack, Opts) -> - done([Token], Handler, Stack, Opts). +done(BadTokens, Handler, Stack, Config) when is_list(BadTokens) -> + ?error([BadTokens, Handler, Stack, Config]); +done(Token, Handler, Stack, Config) -> + done([Token], Handler, Stack, Config). fix_key(Key) when is_atom(Key) -> fix_key(atom_to_binary(Key, utf8)); fix_key(Key) when is_binary(Key) -> Key. -clean_string(Bin, Opts) -> jsx_utils:clean_string(Bin, Opts). +clean_string(Bin, Config) -> jsx_utils:clean_string(Bin, Config). @@ -176,7 +176,7 @@ decode_test_() -> { Title, ?_assertEqual( Events ++ [end_json], - value(Events ++ [end_json], {jsx, []}, [], #opts{}) + value(Events ++ [end_json], {jsx, []}, [], #config{}) ) } || {Title, _, _, Events} <- Data ]. diff --git a/src/jsx_to_json.erl b/src/jsx_to_json.erl index df4f4f4..2b3a8b1 100644 --- a/src/jsx_to_json.erl +++ b/src/jsx_to_json.erl @@ -27,49 +27,49 @@ -export([init/1, handle_event/2]). --record(opts, { +-record(config, { space = 0, indent = 0, depth = 0 }). --type opts() :: list(). +-type config() :: list(). --spec to_json(Source::any(), Opts::opts()) -> binary(). +-spec to_json(Source::any(), Config::config()) -> binary(). -to_json(Source, Opts) when is_list(Opts) -> - (jsx:encoder(?MODULE, Opts, jsx_utils:extract_opts(Opts ++ [escaped_strings])))(Source). +to_json(Source, Config) when is_list(Config) -> + (jsx:encoder(?MODULE, Config, jsx_utils:extract_config(Config ++ [escaped_strings])))(Source). --spec format(Source::binary(), Opts::opts()) -> binary(). +-spec format(Source::binary(), Config::config()) -> binary(). -format(Source, Opts) when is_binary(Source) andalso is_list(Opts) -> - (jsx:decoder(?MODULE, Opts, jsx_utils:extract_opts(Opts ++ [escaped_strings])))(Source). +format(Source, Config) when is_binary(Source) andalso is_list(Config) -> + (jsx:decoder(?MODULE, Config, jsx_utils:extract_config(Config ++ [escaped_strings])))(Source). -parse_opts(Opts) -> parse_opts(Opts, #opts{}). +parse_config(Config) -> parse_config(Config, #config{}). -parse_opts([{space, Val}|Rest], Opts) when is_integer(Val), Val > 0 -> - parse_opts(Rest, Opts#opts{space = Val}); -parse_opts([space|Rest], Opts) -> - parse_opts(Rest, Opts#opts{space = 1}); -parse_opts([{indent, Val}|Rest], Opts) when is_integer(Val), Val > 0 -> - parse_opts(Rest, Opts#opts{indent = Val}); -parse_opts([indent|Rest], Opts) -> - parse_opts(Rest, Opts#opts{indent = 1}); -parse_opts([{K, _}|Rest] = Options, Opts) -> +parse_config([{space, Val}|Rest], Config) when is_integer(Val), Val > 0 -> + parse_config(Rest, Config#config{space = Val}); +parse_config([space|Rest], Config) -> + parse_config(Rest, Config#config{space = 1}); +parse_config([{indent, Val}|Rest], Config) when is_integer(Val), Val > 0 -> + parse_config(Rest, Config#config{indent = Val}); +parse_config([indent|Rest], Config) -> + parse_config(Rest, Config#config{indent = 1}); +parse_config([{K, _}|Rest] = Options, Config) -> case lists:member(K, jsx_utils:valid_flags()) of - true -> parse_opts(Rest, Opts) - ; false -> erlang:error(badarg, [Options, Opts]) + true -> parse_config(Rest, Config) + ; false -> erlang:error(badarg, [Options, Config]) end; -parse_opts([K|Rest] = Options, Opts) -> +parse_config([K|Rest] = Options, Config) -> case lists:member(K, jsx_utils:valid_flags()) of - true -> parse_opts(Rest, Opts) - ; false -> erlang:error(badarg, [Options, Opts]) + true -> parse_config(Rest, Config) + ; false -> erlang:error(badarg, [Options, Config]) end; -parse_opts([], Opts) -> - Opts. +parse_config([], Config) -> + Config. @@ -85,97 +85,97 @@ parse_opts([], Opts) -> -init(Opts) -> {start, [], parse_opts(Opts)}. +init(Config) -> {start, [], parse_config(Config)}. -handle_event(Event, {start, Acc, Opts}) -> +handle_event(Event, {start, Acc, Config}) -> case Event of - {Type, Value} -> {[], [Acc, encode(Type, Value, Opts)], Opts} - ; start_object -> {[object_start], [Acc, ?start_object], Opts} - ; start_array -> {[array_start], [Acc, ?start_array], Opts} + {Type, Value} -> {[], [Acc, encode(Type, Value, Config)], Config} + ; start_object -> {[object_start], [Acc, ?start_object], Config} + ; start_array -> {[array_start], [Acc, ?start_array], Config} end; -handle_event(Event, {[object_start|Stack], Acc, OldOpts = #opts{depth = Depth}}) -> - Opts = OldOpts#opts{depth = Depth + 1}, +handle_event(Event, {[object_start|Stack], Acc, OldConfig = #config{depth = Depth}}) -> + Config = OldConfig#config{depth = Depth + 1}, case Event of {key, Key} -> - {[object_value|Stack], [Acc, indent(Opts), encode(string, Key, Opts), ?colon, space(Opts)], Opts} + {[object_value|Stack], [Acc, indent(Config), encode(string, Key, Config), ?colon, space(Config)], Config} ; end_object -> - {Stack, [Acc, ?end_object], OldOpts} + {Stack, [Acc, ?end_object], OldConfig} end; -handle_event(Event, {[object_value|Stack], Acc, Opts}) -> +handle_event(Event, {[object_value|Stack], Acc, Config}) -> case Event of {Type, Value} when Type == string; Type == literal; Type == integer; Type == float -> - {[key|Stack], [Acc, encode(Type, Value, Opts)], Opts} - ; start_object -> {[object_start, key|Stack], [Acc, ?start_object], Opts} - ; start_array -> {[array_start, key|Stack], [Acc, ?start_array], Opts} + {[key|Stack], [Acc, encode(Type, Value, Config)], Config} + ; start_object -> {[object_start, key|Stack], [Acc, ?start_object], Config} + ; start_array -> {[array_start, key|Stack], [Acc, ?start_array], Config} end; -handle_event(Event, {[key|Stack], Acc, Opts = #opts{depth = Depth}}) -> +handle_event(Event, {[key|Stack], Acc, Config = #config{depth = Depth}}) -> case Event of {key, Key} -> - {[object_value|Stack], [Acc, ?comma, indent_or_space(Opts), encode(string, Key, Opts), ?colon, space(Opts)], Opts} + {[object_value|Stack], [Acc, ?comma, indent_or_space(Config), encode(string, Key, Config), ?colon, space(Config)], Config} ; end_object -> - NewOpts = Opts#opts{depth = Depth - 1}, - {Stack, [Acc, indent(NewOpts), ?end_object], NewOpts} + NewConfig = Config#config{depth = Depth - 1}, + {Stack, [Acc, indent(NewConfig), ?end_object], NewConfig} end; -handle_event(Event, {[array_start|Stack], Acc, OldOpts = #opts{depth = Depth}}) -> - Opts = OldOpts#opts{depth = Depth + 1}, +handle_event(Event, {[array_start|Stack], Acc, OldConfig = #config{depth = Depth}}) -> + Config = OldConfig#config{depth = Depth + 1}, case Event of {Type, Value} when Type == string; Type == literal; Type == integer; Type == float -> - {[array|Stack], [Acc, indent(Opts), encode(Type, Value, Opts)], Opts} - ; start_object -> {[object_start, array|Stack], [Acc, indent(Opts), ?start_object], Opts} - ; start_array -> {[array_start, array|Stack], [Acc, indent(Opts), ?start_array], Opts} - ; end_array -> {Stack, [Acc, ?end_array], OldOpts} + {[array|Stack], [Acc, indent(Config), encode(Type, Value, Config)], Config} + ; start_object -> {[object_start, array|Stack], [Acc, indent(Config), ?start_object], Config} + ; start_array -> {[array_start, array|Stack], [Acc, indent(Config), ?start_array], Config} + ; end_array -> {Stack, [Acc, ?end_array], OldConfig} end; -handle_event(Event, {[array|Stack], Acc, Opts = #opts{depth = Depth}}) -> +handle_event(Event, {[array|Stack], Acc, Config = #config{depth = Depth}}) -> case Event of {Type, Value} when Type == string; Type == literal; Type == integer; Type == float -> - {[array|Stack], [Acc, ?comma, indent_or_space(Opts), encode(Type, Value, Opts)], Opts} + {[array|Stack], [Acc, ?comma, indent_or_space(Config), encode(Type, Value, Config)], Config} ; end_array -> - NewOpts = Opts#opts{depth = Depth - 1}, - {Stack, [Acc, indent(NewOpts), ?end_array], NewOpts} - ; start_object -> {[object_start, array|Stack], [Acc, ?comma, indent_or_space(Opts), ?start_object], Opts} - ; start_array -> {[array_start, array|Stack], [Acc, ?comma, indent_or_space(Opts), ?start_array], Opts} + NewConfig = Config#config{depth = Depth - 1}, + {Stack, [Acc, indent(NewConfig), ?end_array], NewConfig} + ; start_object -> {[object_start, array|Stack], [Acc, ?comma, indent_or_space(Config), ?start_object], Config} + ; start_array -> {[array_start, array|Stack], [Acc, ?comma, indent_or_space(Config), ?start_array], Config} end; -handle_event(end_json, {[], Acc, _Opts}) -> unicode:characters_to_binary(Acc, utf8). +handle_event(end_json, {[], Acc, _Config}) -> unicode:characters_to_binary(Acc, utf8). -encode(string, String, _Opts) -> +encode(string, String, _Config) -> [?quote, String, ?quote]; -encode(literal, Literal, _Opts) -> +encode(literal, Literal, _Config) -> erlang:atom_to_list(Literal); -encode(integer, Integer, _Opts) -> +encode(integer, Integer, _Config) -> erlang:integer_to_list(Integer); -encode(float, Float, _Opts) -> +encode(float, Float, _Config) -> [Output] = io_lib:format("~p", [Float]), Output. -space(Opts) -> - case Opts#opts.space of +space(Config) -> + case Config#config.space of 0 -> [] ; X when X > 0 -> binary:copy(?space, X) end. -indent(Opts) -> - case Opts#opts.indent of +indent(Config) -> + case Config#config.indent of 0 -> [] ; X when X > 0 -> Indent = binary:copy(?space, X), - indent(Indent, Opts#opts.depth, [?newline]) + indent(Indent, Config#config.depth, [?newline]) end. indent(_Indent, 0, Acc) -> Acc; indent(Indent, N, Acc) -> indent(Indent, N - 1, [Acc, Indent]). -indent_or_space(Opts) -> - case Opts#opts.indent > 0 of - true -> indent(Opts) - ; false -> space(Opts) +indent_or_space(Config) -> + case Config#config.indent > 0 of + true -> indent(Config) + ; false -> space(Config) end. @@ -185,56 +185,56 @@ indent_or_space(Opts) -> -include_lib("eunit/include/eunit.hrl"). -opts_test_() -> +config_test_() -> [ - {"empty opts", ?_assertEqual(#opts{}, parse_opts([]))}, + {"empty config", ?_assertEqual(#config{}, parse_config([]))}, {"unspecified indent/space", ?_assertEqual( - #opts{space=1, indent=1}, - parse_opts([space, indent]) + #config{space=1, indent=1}, + parse_config([space, indent]) )}, {"specific indent", ?_assertEqual( - #opts{indent=4}, - parse_opts([{indent, 4}]) + #config{indent=4}, + parse_config([{indent, 4}]) )}, {"specific space", ?_assertEqual( - #opts{space=2}, - parse_opts([{space, 2}]) + #config{space=2}, + parse_config([{space, 2}]) )}, {"specific space and indent", ?_assertEqual( - #opts{space=2, indent=2}, - parse_opts([{space, 2}, {indent, 2}]) + #config{space=2, indent=2}, + parse_config([{space, 2}, {indent, 2}]) )}, - {"invalid opt flag", ?_assertError(badarg, parse_opts([error]))}, - {"invalid opt tuple", ?_assertError(badarg, parse_opts([{error, true}]))} + {"invalid opt flag", ?_assertError(badarg, parse_config([error]))}, + {"invalid opt tuple", ?_assertError(badarg, parse_config([{error, true}]))} ]. space_test_() -> [ - {"no space", ?_assertEqual([], space(#opts{space=0}))}, - {"one space", ?_assertEqual(<<" ">>, space(#opts{space=1}))}, - {"four spaces", ?_assertEqual(<<" ">>, space(#opts{space=4}))} + {"no space", ?_assertEqual([], space(#config{space=0}))}, + {"one space", ?_assertEqual(<<" ">>, space(#config{space=1}))}, + {"four spaces", ?_assertEqual(<<" ">>, space(#config{space=4}))} ]. indent_test_() -> [ - {"no indent", ?_assertEqual([], indent(#opts{indent=0, depth=1}))}, + {"no indent", ?_assertEqual([], indent(#config{indent=0, depth=1}))}, {"indent 1 depth 1", ?_assertEqual( [[?newline], ?space], - indent(#opts{indent=1, depth=1}) + indent(#config{indent=1, depth=1}) )}, {"indent 1 depth 2", ?_assertEqual( [[[?newline], ?space], ?space], - indent(#opts{indent=1, depth=2}) + indent(#config{indent=1, depth=2}) )}, {"indent 4 depth 1", ?_assertEqual( [[?newline], <<" ">>], - indent(#opts{indent=4, depth=1}) + indent(#config{indent=4, depth=1}) )}, {"indent 4 depth 2", ?_assertEqual( [[[?newline], <<" ">>], <<" ">>], - indent(#opts{indent=4, depth=2}) + indent(#config{indent=4, depth=2}) )} ]. @@ -243,48 +243,48 @@ indent_or_space_test_() -> [ {"no indent so space", ?_assertEqual( <<" ">>, - indent_or_space(#opts{space=1, indent=0, depth=1}) + indent_or_space(#config{space=1, indent=0, depth=1}) )}, {"indent so no space", ?_assertEqual( [[?newline], ?space], - indent_or_space(#opts{space=1, indent=1, depth=1}) + indent_or_space(#config{space=1, indent=1, depth=1}) )} ]. format_test_() -> [ - {"0.0", ?_assert(encode(float, 0.0, #opts{}) =:= "0.0")}, - {"1.0", ?_assert(encode(float, 1.0, #opts{}) =:= "1.0")}, - {"-1.0", ?_assert(encode(float, -1.0, #opts{}) =:= "-1.0")}, + {"0.0", ?_assert(encode(float, 0.0, #config{}) =:= "0.0")}, + {"1.0", ?_assert(encode(float, 1.0, #config{}) =:= "1.0")}, + {"-1.0", ?_assert(encode(float, -1.0, #config{}) =:= "-1.0")}, {"3.1234567890987654321", ?_assert( - encode(float, 3.1234567890987654321, #opts{}) =:= "3.1234567890987655") + encode(float, 3.1234567890987654321, #config{}) =:= "3.1234567890987655") }, - {"1.0e23", ?_assert(encode(float, 1.0e23, #opts{}) =:= "1.0e23")}, - {"0.3", ?_assert(encode(float, 3.0/10.0, #opts{}) =:= "0.3")}, - {"0.0001", ?_assert(encode(float, 0.0001, #opts{}) =:= "0.0001")}, - {"0.00001", ?_assert(encode(float, 0.00001, #opts{}) =:= "1.0e-5")}, - {"0.00000001", ?_assert(encode(float, 0.00000001, #opts{}) =:= "1.0e-8")}, - {"1.0e-323", ?_assert(encode(float, 1.0e-323, #opts{}) =:= "1.0e-323")}, - {"1.0e308", ?_assert(encode(float, 1.0e308, #opts{}) =:= "1.0e308")}, + {"1.0e23", ?_assert(encode(float, 1.0e23, #config{}) =:= "1.0e23")}, + {"0.3", ?_assert(encode(float, 3.0/10.0, #config{}) =:= "0.3")}, + {"0.0001", ?_assert(encode(float, 0.0001, #config{}) =:= "0.0001")}, + {"0.00001", ?_assert(encode(float, 0.00001, #config{}) =:= "1.0e-5")}, + {"0.00000001", ?_assert(encode(float, 0.00000001, #config{}) =:= "1.0e-8")}, + {"1.0e-323", ?_assert(encode(float, 1.0e-323, #config{}) =:= "1.0e-323")}, + {"1.0e308", ?_assert(encode(float, 1.0e308, #config{}) =:= "1.0e308")}, {"min normalized float", ?_assert( - encode(float, math:pow(2, -1022), #opts{}) =:= "2.2250738585072014e-308" + encode(float, math:pow(2, -1022), #config{}) =:= "2.2250738585072014e-308" ) }, {"max normalized float", ?_assert( - encode(float, (2 - math:pow(2, -52)) * math:pow(2, 1023), #opts{}) + encode(float, (2 - math:pow(2, -52)) * math:pow(2, 1023), #config{}) =:= "1.7976931348623157e308" ) }, {"min denormalized float", - ?_assert(encode(float, math:pow(2, -1074), #opts{}) =:= "5.0e-324") + ?_assert(encode(float, math:pow(2, -1074), #config{}) =:= "5.0e-324") }, {"max denormalized float", ?_assert( - encode(float, (1 - math:pow(2, -52)) * math:pow(2, -1022), #opts{}) + encode(float, (1 - math:pow(2, -52)) * math:pow(2, -1022), #config{}) =:= "2.225073858507201e-308" ) } @@ -297,7 +297,7 @@ handle_event_test_() -> { Title, ?_assertEqual( JSON, - lists:foldl(fun handle_event/2, {start, [], #opts{}}, Events ++ [end_json]) + lists:foldl(fun handle_event/2, {start, [], #config{}}, Events ++ [end_json]) ) } || {Title, JSON, _, Events} <- Data ]. diff --git a/src/jsx_to_term.erl b/src/jsx_to_term.erl index 792b6d6..b27d9b9 100644 --- a/src/jsx_to_term.erl +++ b/src/jsx_to_term.erl @@ -27,12 +27,12 @@ -export([init/1, handle_event/2]). --record(opts, { +-record(config, { labels = binary, post_decode = false }). --type opts() :: list(). +-type config() :: list(). -type json_value() :: list({binary(), json_value()}) | list(json_value()) @@ -44,74 +44,74 @@ | binary(). --spec to_term(Source::binary(), Opts::opts()) -> json_value(). +-spec to_term(Source::binary(), Config::config()) -> json_value(). -to_term(Source, Opts) when is_list(Opts) -> - (jsx:decoder(?MODULE, Opts, jsx_utils:extract_opts(Opts)))(Source). +to_term(Source, Config) when is_list(Config) -> + (jsx:decoder(?MODULE, Config, jsx_utils:extract_config(Config)))(Source). -parse_opts(Opts) -> parse_opts(Opts, #opts{}). +parse_config(Config) -> parse_config(Config, #config{}). -parse_opts([{labels, Val}|Rest], Opts) +parse_config([{labels, Val}|Rest], Config) when Val == binary; Val == atom; Val == existing_atom -> - parse_opts(Rest, Opts#opts{labels = Val}); -parse_opts([labels|Rest], Opts) -> - parse_opts(Rest, Opts#opts{labels = binary}); -parse_opts([{post_decode, F}|Rest], Opts=#opts{post_decode=false}) when is_function(F, 1) -> - parse_opts(Rest, Opts#opts{post_decode=F}); -parse_opts([{K, _}|Rest] = Options, Opts) -> + parse_config(Rest, Config#config{labels = Val}); +parse_config([labels|Rest], Config) -> + parse_config(Rest, Config#config{labels = binary}); +parse_config([{post_decode, F}|Rest], Config=#config{post_decode=false}) when is_function(F, 1) -> + parse_config(Rest, Config#config{post_decode=F}); +parse_config([{K, _}|Rest] = Options, Config) -> case lists:member(K, jsx_utils:valid_flags()) of - true -> parse_opts(Rest, Opts) - ; false -> erlang:error(badarg, [Options, Opts]) + true -> parse_config(Rest, Config) + ; false -> erlang:error(badarg, [Options, Config]) end; -parse_opts([K|Rest] = Options, Opts) -> +parse_config([K|Rest] = Options, Config) -> case lists:member(K, jsx_utils:valid_flags()) of - true -> parse_opts(Rest, Opts) - ; false -> erlang:error(badarg, [Options, Opts]) + true -> parse_config(Rest, Config) + ; false -> erlang:error(badarg, [Options, Config]) end; -parse_opts([], Opts) -> - Opts. +parse_config([], Config) -> + Config. -init(Opts) -> {[[]], parse_opts(Opts)}. +init(Config) -> {[[]], parse_config(Config)}. -handle_event(end_json, {[[Terms]], _Opts}) -> Terms; +handle_event(end_json, {[[Terms]], _Config}) -> Terms; -handle_event(start_object, {Terms, Opts}) -> {[[]|Terms], Opts}; -handle_event(end_object, {[[], {key, Key}, Last|Terms], Opts}) -> - {[[{Key, post_decode([{}], Opts)}] ++ Last] ++ Terms, Opts}; -handle_event(end_object, {[Object, {key, Key}, Last|Terms], Opts}) -> - {[[{Key, post_decode(lists:reverse(Object), Opts)}] ++ Last] ++ Terms, Opts}; -handle_event(end_object, {[[], Last|Terms], Opts}) -> - {[[post_decode([{}], Opts)] ++ Last] ++ Terms, Opts}; -handle_event(end_object, {[Object, Last|Terms], Opts}) -> - {[[post_decode(lists:reverse(Object), Opts)] ++ Last] ++ Terms, Opts}; +handle_event(start_object, {Terms, Config}) -> {[[]|Terms], Config}; +handle_event(end_object, {[[], {key, Key}, Last|Terms], Config}) -> + {[[{Key, post_decode([{}], Config)}] ++ Last] ++ Terms, Config}; +handle_event(end_object, {[Object, {key, Key}, Last|Terms], Config}) -> + {[[{Key, post_decode(lists:reverse(Object), Config)}] ++ Last] ++ Terms, Config}; +handle_event(end_object, {[[], Last|Terms], Config}) -> + {[[post_decode([{}], Config)] ++ Last] ++ Terms, Config}; +handle_event(end_object, {[Object, Last|Terms], Config}) -> + {[[post_decode(lists:reverse(Object), Config)] ++ Last] ++ Terms, Config}; -handle_event(start_array, {Terms, Opts}) -> {[[]|Terms], Opts}; -handle_event(end_array, {[List, {key, Key}, Last|Terms], Opts}) -> - {[[{Key, post_decode(lists:reverse(List), Opts)}] ++ Last] ++ Terms, Opts}; -handle_event(end_array, {[List, Last|Terms], Opts}) -> - {[[post_decode(lists:reverse(List), Opts)] ++ Last] ++ Terms, Opts}; +handle_event(start_array, {Terms, Config}) -> {[[]|Terms], Config}; +handle_event(end_array, {[List, {key, Key}, Last|Terms], Config}) -> + {[[{Key, post_decode(lists:reverse(List), Config)}] ++ Last] ++ Terms, Config}; +handle_event(end_array, {[List, Last|Terms], Config}) -> + {[[post_decode(lists:reverse(List), Config)] ++ Last] ++ Terms, Config}; -handle_event({key, Key}, {Terms, Opts}) -> {[{key, format_key(Key, Opts)}] ++ Terms, Opts}; +handle_event({key, Key}, {Terms, Config}) -> {[{key, format_key(Key, Config)}] ++ Terms, Config}; -handle_event({_, Event}, {[{key, Key}, Last|Terms], Opts}) -> - {[[{Key, post_decode(Event, Opts)}] ++ Last] ++ Terms, Opts}; -handle_event({_, Event}, {[Last|Terms], Opts}) -> - {[[post_decode(Event, Opts)] ++ Last] ++ Terms, Opts}. +handle_event({_, Event}, {[{key, Key}, Last|Terms], Config}) -> + {[[{Key, post_decode(Event, Config)}] ++ Last] ++ Terms, Config}; +handle_event({_, Event}, {[Last|Terms], Config}) -> + {[[post_decode(Event, Config)] ++ Last] ++ Terms, Config}. -format_key(Key, Opts) -> - case Opts#opts.labels of +format_key(Key, Config) -> + case Config#config.labels of binary -> Key ; atom -> binary_to_atom(Key, utf8) ; existing_atom -> binary_to_existing_atom(Key, utf8) end. -post_decode(Value, #opts{post_decode=false}) -> Value; -post_decode(Value, Opts) -> (Opts#opts.post_decode)(Value). +post_decode(Value, #config{post_decode=false}) -> Value; +post_decode(Value, Config) -> (Config#config.post_decode)(Value). %% eunit tests @@ -120,40 +120,40 @@ post_decode(Value, Opts) -> (Opts#opts.post_decode)(Value). -include_lib("eunit/include/eunit.hrl"). -opts_test_() -> +config_test_() -> %% for post_decode tests F = fun(X) -> X end, G = fun(X, Y) -> {X, Y} end, [ - {"empty opts", ?_assertEqual(#opts{}, parse_opts([]))}, - {"implicit binary labels", ?_assertEqual(#opts{}, parse_opts([labels]))}, - {"binary labels", ?_assertEqual(#opts{}, parse_opts([{labels, binary}]))}, - {"atom labels", ?_assertEqual(#opts{labels=atom}, parse_opts([{labels, atom}]))}, + {"empty config", ?_assertEqual(#config{}, parse_config([]))}, + {"implicit binary labels", ?_assertEqual(#config{}, parse_config([labels]))}, + {"binary labels", ?_assertEqual(#config{}, parse_config([{labels, binary}]))}, + {"atom labels", ?_assertEqual(#config{labels=atom}, parse_config([{labels, atom}]))}, {"existing atom labels", ?_assertEqual( - #opts{labels=existing_atom}, - parse_opts([{labels, existing_atom}]) + #config{labels=existing_atom}, + parse_config([{labels, existing_atom}]) )}, {"post decode", ?_assertEqual( - #opts{post_decode=F}, - parse_opts([{post_decode, F}]) + #config{post_decode=F}, + parse_config([{post_decode, F}]) )}, - {"post decode wrong arity", ?_assertError(badarg, parse_opts([{post_decode, G}]))}, - {"invalid opt flag", ?_assertError(badarg, parse_opts([error]))}, - {"invalid opt tuple", ?_assertError(badarg, parse_opts([{error, true}]))} + {"post decode wrong arity", ?_assertError(badarg, parse_config([{post_decode, G}]))}, + {"invalid opt flag", ?_assertError(badarg, parse_config([error]))}, + {"invalid opt tuple", ?_assertError(badarg, parse_config([{error, true}]))} ]. format_key_test_() -> [ - {"binary key", ?_assertEqual(<<"key">>, format_key(<<"key">>, #opts{labels=binary}))}, - {"atom key", ?_assertEqual(key, format_key(<<"key">>, #opts{labels=atom}))}, + {"binary key", ?_assertEqual(<<"key">>, format_key(<<"key">>, #config{labels=binary}))}, + {"atom key", ?_assertEqual(key, format_key(<<"key">>, #config{labels=atom}))}, {"existing atom key", ?_assertEqual( key, - format_key(<<"key">>, #opts{labels=existing_atom}) + format_key(<<"key">>, #config{labels=existing_atom}) )}, {"nonexisting atom key", ?_assertError( badarg, - format_key(<<"nonexistentatom">>, #opts{labels=existing_atom}) + format_key(<<"nonexistentatom">>, #config{labels=existing_atom}) )} ]. @@ -177,7 +177,7 @@ post_decoders_test_() -> [ {"no post_decode", ?_assertEqual( Events, - [ post_decode(Event, #opts{}) || Event <- Events ] + [ post_decode(Event, #config{}) || Event <- Events ] )}, {"replace arrays with empty arrays", ?_assertEqual( [ @@ -195,7 +195,7 @@ post_decoders_test_() -> 1, 1.0 ], - [ post_decode(Event, #opts{ + [ post_decode(Event, #config{ post_decode=fun([T|_] = V) when is_tuple(T) -> V; (V) when is_list(V) -> []; (V) -> V end }) || Event <- Events ] @@ -216,7 +216,7 @@ post_decoders_test_() -> 1, 1.0 ], - [ post_decode(Event, #opts{ + [ post_decode(Event, #config{ post_decode=fun([T|_]) when is_tuple(T) -> [{}]; (V) -> V end }) || Event <- Events ] @@ -237,7 +237,7 @@ post_decoders_test_() -> false, false ], - [ post_decode(Event, #opts{ + [ post_decode(Event, #config{ post_decode=fun(V) when is_list(V) -> V; (_) -> false end }) || Event <- Events ] @@ -258,7 +258,7 @@ post_decoders_test_() -> 1, 1.0 ], - [ post_decode(Event, #opts{ + [ post_decode(Event, #config{ post_decode=fun(V) when is_atom(V) -> unicode:characters_to_binary(atom_to_list(V)); (V) -> V end }) || Event <- Events ] @@ -273,7 +273,7 @@ handle_event_test_() -> { Title, ?_assertEqual( Term, - lists:foldl(fun handle_event/2, {[[]], #opts{}}, Events ++ [end_json]) + lists:foldl(fun handle_event/2, {[[]], #config{}}, Events ++ [end_json]) ) } || {Title, _, Term, Events} <- Data ]. diff --git a/src/jsx_utils.erl b/src/jsx_utils.erl index b3125d3..b50172a 100644 --- a/src/jsx_utils.erl +++ b/src/jsx_utils.erl @@ -23,70 +23,70 @@ -module(jsx_utils). --export([parse_opts/1]). --export([extract_opts/1, valid_flags/0]). +-export([parse_config/1]). +-export([extract_config/1, valid_flags/0]). -export([json_escape_sequence/1]). -export([clean_string/2]). --include("jsx_opts.hrl"). +-include("jsx_config.hrl"). -%% parsing of jsx opts -parse_opts(Opts) -> - parse_opts(Opts, #opts{}). +%% parsing of jsx config +parse_config(Config) -> + parse_config(Config, #config{}). -parse_opts([], Opts) -> - Opts; -parse_opts([replaced_bad_utf8|Rest], Opts) -> - parse_opts(Rest, Opts#opts{replaced_bad_utf8=true}); -parse_opts([escaped_forward_slashes|Rest], Opts) -> - parse_opts(Rest, Opts#opts{escaped_forward_slashes=true}); -parse_opts([explicit_end|Rest], Opts) -> - parse_opts(Rest, Opts#opts{explicit_end=true}); -parse_opts([single_quoted_strings|Rest], Opts) -> - parse_opts(Rest, Opts#opts{single_quoted_strings=true}); -parse_opts([unescaped_jsonp|Rest], Opts) -> - parse_opts(Rest, Opts#opts{unescaped_jsonp=true}); -parse_opts([comments|Rest], Opts) -> - parse_opts(Rest, Opts#opts{comments=true}); -parse_opts([escaped_strings|Rest], Opts) -> - parse_opts(Rest, Opts#opts{escaped_strings=true}); -parse_opts([dirty_strings|Rest], Opts) -> - parse_opts(Rest, Opts#opts{dirty_strings=true}); -parse_opts([ignored_bad_escapes|Rest], Opts) -> - parse_opts(Rest, Opts#opts{ignored_bad_escapes=true}); -parse_opts([relax|Rest], Opts) -> - parse_opts(Rest, Opts#opts{ +parse_config([], Config) -> + Config; +parse_config([replaced_bad_utf8|Rest], Config) -> + parse_config(Rest, Config#config{replaced_bad_utf8=true}); +parse_config([escaped_forward_slashes|Rest], Config) -> + parse_config(Rest, Config#config{escaped_forward_slashes=true}); +parse_config([explicit_end|Rest], Config) -> + parse_config(Rest, Config#config{explicit_end=true}); +parse_config([single_quoted_strings|Rest], Config) -> + parse_config(Rest, Config#config{single_quoted_strings=true}); +parse_config([unescaped_jsonp|Rest], Config) -> + parse_config(Rest, Config#config{unescaped_jsonp=true}); +parse_config([comments|Rest], Config) -> + parse_config(Rest, Config#config{comments=true}); +parse_config([escaped_strings|Rest], Config) -> + parse_config(Rest, Config#config{escaped_strings=true}); +parse_config([dirty_strings|Rest], Config) -> + parse_config(Rest, Config#config{dirty_strings=true}); +parse_config([ignored_bad_escapes|Rest], Config) -> + parse_config(Rest, Config#config{ignored_bad_escapes=true}); +parse_config([relax|Rest], Config) -> + parse_config(Rest, Config#config{ replaced_bad_utf8 = true, single_quoted_strings = true, comments = true, ignored_bad_escapes = true }); -parse_opts([{pre_encode, Encoder}|Rest] = Options, Opts) when is_function(Encoder, 1) -> - case Opts#opts.pre_encode of - false -> parse_opts(Rest, Opts#opts{pre_encode=Encoder}) - ; _ -> erlang:error(badarg, [Options, Opts]) +parse_config([{pre_encode, Encoder}|Rest] = Options, Config) when is_function(Encoder, 1) -> + case Config#config.pre_encode of + false -> parse_config(Rest, Config#config{pre_encode=Encoder}) + ; _ -> erlang:error(badarg, [Options, Config]) end; %% deprecated flags -parse_opts([{pre_encoder, Encoder}|Rest] = Options, Opts) when is_function(Encoder, 1) -> - case Opts#opts.pre_encode of - false -> parse_opts(Rest, Opts#opts{pre_encode=Encoder}) - ; _ -> erlang:error(badarg, [Options, Opts]) +parse_config([{pre_encoder, Encoder}|Rest] = Options, Config) when is_function(Encoder, 1) -> + case Config#config.pre_encode of + false -> parse_config(Rest, Config#config{pre_encode=Encoder}) + ; _ -> erlang:error(badarg, [Options, Config]) end; -parse_opts([loose_unicode|Rest], Opts) -> - parse_opts(Rest, Opts#opts{replaced_bad_utf8=true}); -parse_opts([escape_forward_slash|Rest], Opts) -> - parse_opts(Rest, Opts#opts{escaped_forward_slashes=true}); -parse_opts([single_quotes|Rest], Opts) -> - parse_opts(Rest, Opts#opts{single_quoted_strings=true}); -parse_opts([no_jsonp_escapes|Rest], Opts) -> - parse_opts(Rest, Opts#opts{unescaped_jsonp=true}); -parse_opts([json_escape|Rest], Opts) -> - parse_opts(Rest, Opts#opts{escaped_strings=true}); -parse_opts([ignore_bad_escapes|Rest], Opts) -> - parse_opts(Rest, Opts#opts{ignored_bad_escapes=true}); -parse_opts(Options, Opts) -> - erlang:error(badarg, [Options, Opts]). +parse_config([loose_unicode|Rest], Config) -> + parse_config(Rest, Config#config{replaced_bad_utf8=true}); +parse_config([escape_forward_slash|Rest], Config) -> + parse_config(Rest, Config#config{escaped_forward_slashes=true}); +parse_config([single_quotes|Rest], Config) -> + parse_config(Rest, Config#config{single_quoted_strings=true}); +parse_config([no_jsonp_escapes|Rest], Config) -> + parse_config(Rest, Config#config{unescaped_jsonp=true}); +parse_config([json_escape|Rest], Config) -> + parse_config(Rest, Config#config{escaped_strings=true}); +parse_config([ignore_bad_escapes|Rest], Config) -> + parse_config(Rest, Config#config{ignored_bad_escapes=true}); +parse_config(Options, Config) -> + erlang:error(badarg, [Options, Config]). valid_flags() -> @@ -113,19 +113,19 @@ valid_flags() -> ]. -extract_opts(Opts) -> - extract_parser_opts(Opts, []). +extract_config(Config) -> + extract_parser_config(Config, []). -extract_parser_opts([], Acc) -> Acc; -extract_parser_opts([{K,V}|Rest], Acc) -> +extract_parser_config([], Acc) -> Acc; +extract_parser_config([{K,V}|Rest], Acc) -> case lists:member(K, valid_flags()) of - true -> extract_parser_opts(Rest, [{K,V}] ++ Acc) - ; false -> extract_parser_opts(Rest, Acc) + true -> extract_parser_config(Rest, [{K,V}] ++ Acc) + ; false -> extract_parser_config(Rest, Acc) end; -extract_parser_opts([K|Rest], Acc) -> +extract_parser_config([K|Rest], Acc) -> case lists:member(K, valid_flags()) of - true -> extract_parser_opts(Rest, [K] ++ Acc) - ; false -> extract_parser_opts(Rest, Acc) + true -> extract_parser_config(Rest, [K] ++ Acc) + ; false -> extract_parser_config(Rest, Acc) end. @@ -144,10 +144,10 @@ to_hex(15) -> $f; to_hex(X) -> X + 48. %% ascii "1" is [49], "2" is [50], etc... -clean_string(Bin, #opts{dirty_strings=true}) -> Bin; -clean_string(Bin, Opts) -> - case Opts#opts.replaced_bad_utf8 orelse Opts#opts.escaped_strings of - true -> clean(Bin, [], Opts) +clean_string(Bin, #config{dirty_strings=true}) -> Bin; +clean_string(Bin, Config) -> + case Config#config.replaced_bad_utf8 orelse Config#config.escaped_strings of + true -> clean(Bin, [], Config) ; false -> ensure_clean(Bin), Bin end. @@ -305,197 +305,197 @@ ensure_clean(Bin) -> erlang:error(badarg, [Bin]). %% escape and/or replace bad codepoints if requested -clean(<<>>, Acc, _Opts) -> unicode:characters_to_binary(lists:reverse(Acc)); -clean(<<0, Rest/binary>>, Acc, Opts) -> clean(Rest, maybe_replace(0, Opts) ++ Acc, Opts); -clean(<<1, Rest/binary>>, Acc, Opts) -> clean(Rest, maybe_replace(1, Opts) ++ Acc, Opts); -clean(<<2, Rest/binary>>, Acc, Opts) -> clean(Rest, maybe_replace(2, Opts) ++ Acc, Opts); -clean(<<3, Rest/binary>>, Acc, Opts) -> clean(Rest, maybe_replace(3, Opts) ++ Acc, Opts); -clean(<<4, Rest/binary>>, Acc, Opts) -> clean(Rest, maybe_replace(4, Opts) ++ Acc, Opts); -clean(<<5, Rest/binary>>, Acc, Opts) -> clean(Rest, maybe_replace(5, Opts) ++ Acc, Opts); -clean(<<6, Rest/binary>>, Acc, Opts) -> clean(Rest, maybe_replace(6, Opts) ++ Acc, Opts); -clean(<<7, Rest/binary>>, Acc, Opts) -> clean(Rest, maybe_replace(7, Opts) ++ Acc, Opts); -clean(<<8, Rest/binary>>, Acc, Opts) -> clean(Rest, maybe_replace(8, Opts) ++ Acc, Opts); -clean(<<9, Rest/binary>>, Acc, Opts) -> clean(Rest, maybe_replace(9, Opts) ++ Acc, Opts); -clean(<<10, Rest/binary>>, Acc, Opts) -> clean(Rest, maybe_replace(10, Opts) ++ Acc, Opts); -clean(<<11, Rest/binary>>, Acc, Opts) -> clean(Rest, maybe_replace(11, Opts) ++ Acc, Opts); -clean(<<12, Rest/binary>>, Acc, Opts) -> clean(Rest, maybe_replace(12, Opts) ++ Acc, Opts); -clean(<<13, Rest/binary>>, Acc, Opts) -> clean(Rest, maybe_replace(13, Opts) ++ Acc, Opts); -clean(<<14, Rest/binary>>, Acc, Opts) -> clean(Rest, maybe_replace(14, Opts) ++ Acc, Opts); -clean(<<15, Rest/binary>>, Acc, Opts) -> clean(Rest, maybe_replace(15, Opts) ++ Acc, Opts); -clean(<<16, Rest/binary>>, Acc, Opts) -> clean(Rest, maybe_replace(16, Opts) ++ Acc, Opts); -clean(<<17, Rest/binary>>, Acc, Opts) -> clean(Rest, maybe_replace(17, Opts) ++ Acc, Opts); -clean(<<18, Rest/binary>>, Acc, Opts) -> clean(Rest, maybe_replace(18, Opts) ++ Acc, Opts); -clean(<<19, Rest/binary>>, Acc, Opts) -> clean(Rest, maybe_replace(19, Opts) ++ Acc, Opts); -clean(<<20, Rest/binary>>, Acc, Opts) -> clean(Rest, maybe_replace(20, Opts) ++ Acc, Opts); -clean(<<21, Rest/binary>>, Acc, Opts) -> clean(Rest, maybe_replace(21, Opts) ++ Acc, Opts); -clean(<<22, Rest/binary>>, Acc, Opts) -> clean(Rest, maybe_replace(22, Opts) ++ Acc, Opts); -clean(<<23, Rest/binary>>, Acc, Opts) -> clean(Rest, maybe_replace(23, Opts) ++ Acc, Opts); -clean(<<24, Rest/binary>>, Acc, Opts) -> clean(Rest, maybe_replace(24, Opts) ++ Acc, Opts); -clean(<<25, Rest/binary>>, Acc, Opts) -> clean(Rest, maybe_replace(25, Opts) ++ Acc, Opts); -clean(<<26, Rest/binary>>, Acc, Opts) -> clean(Rest, maybe_replace(26, Opts) ++ Acc, Opts); -clean(<<27, Rest/binary>>, Acc, Opts) -> clean(Rest, maybe_replace(27, Opts) ++ Acc, Opts); -clean(<<28, Rest/binary>>, Acc, Opts) -> clean(Rest, maybe_replace(28, Opts) ++ Acc, Opts); -clean(<<29, Rest/binary>>, Acc, Opts) -> clean(Rest, maybe_replace(29, Opts) ++ Acc, Opts); -clean(<<30, Rest/binary>>, Acc, Opts) -> clean(Rest, maybe_replace(30, Opts) ++ Acc, Opts); -clean(<<31, Rest/binary>>, Acc, Opts) -> clean(Rest, maybe_replace(31, Opts) ++ Acc, Opts); -clean(<<32, Rest/binary>>, Acc, Opts) -> clean(Rest, [32] ++ Acc, Opts); -clean(<<33, Rest/binary>>, Acc, Opts) -> clean(Rest, [33] ++ Acc, Opts); -clean(<<34, Rest/binary>>, Acc, Opts) -> clean(Rest, maybe_replace(34, Opts) ++ Acc, Opts); -clean(<<35, Rest/binary>>, Acc, Opts) -> clean(Rest, [35] ++ Acc, Opts); -clean(<<36, Rest/binary>>, Acc, Opts) -> clean(Rest, [36] ++ Acc, Opts); -clean(<<37, Rest/binary>>, Acc, Opts) -> clean(Rest, [37] ++ Acc, Opts); -clean(<<38, Rest/binary>>, Acc, Opts) -> clean(Rest, [38] ++ Acc, Opts); -clean(<<39, Rest/binary>>, Acc, Opts) -> clean(Rest, [39] ++ Acc, Opts); -clean(<<40, Rest/binary>>, Acc, Opts) -> clean(Rest, [40] ++ Acc, Opts); -clean(<<41, Rest/binary>>, Acc, Opts) -> clean(Rest, [41] ++ Acc, Opts); -clean(<<42, Rest/binary>>, Acc, Opts) -> clean(Rest, [42] ++ Acc, Opts); -clean(<<43, Rest/binary>>, Acc, Opts) -> clean(Rest, [43] ++ Acc, Opts); -clean(<<44, Rest/binary>>, Acc, Opts) -> clean(Rest, [44] ++ Acc, Opts); -clean(<<45, Rest/binary>>, Acc, Opts) -> clean(Rest, [45] ++ Acc, Opts); -clean(<<46, Rest/binary>>, Acc, Opts) -> clean(Rest, [46] ++ Acc, Opts); -clean(<<47, Rest/binary>>, Acc, Opts) -> clean(Rest, maybe_replace(47, Opts) ++ Acc, Opts); -clean(<<48, Rest/binary>>, Acc, Opts) -> clean(Rest, [48] ++ Acc, Opts); -clean(<<49, Rest/binary>>, Acc, Opts) -> clean(Rest, [49] ++ Acc, Opts); -clean(<<50, Rest/binary>>, Acc, Opts) -> clean(Rest, [50] ++ Acc, Opts); -clean(<<51, Rest/binary>>, Acc, Opts) -> clean(Rest, [51] ++ Acc, Opts); -clean(<<52, Rest/binary>>, Acc, Opts) -> clean(Rest, [52] ++ Acc, Opts); -clean(<<53, Rest/binary>>, Acc, Opts) -> clean(Rest, [53] ++ Acc, Opts); -clean(<<54, Rest/binary>>, Acc, Opts) -> clean(Rest, [54] ++ Acc, Opts); -clean(<<55, Rest/binary>>, Acc, Opts) -> clean(Rest, [55] ++ Acc, Opts); -clean(<<56, Rest/binary>>, Acc, Opts) -> clean(Rest, [56] ++ Acc, Opts); -clean(<<57, Rest/binary>>, Acc, Opts) -> clean(Rest, [57] ++ Acc, Opts); -clean(<<58, Rest/binary>>, Acc, Opts) -> clean(Rest, [58] ++ Acc, Opts); -clean(<<59, Rest/binary>>, Acc, Opts) -> clean(Rest, [59] ++ Acc, Opts); -clean(<<60, Rest/binary>>, Acc, Opts) -> clean(Rest, [60] ++ Acc, Opts); -clean(<<61, Rest/binary>>, Acc, Opts) -> clean(Rest, [61] ++ Acc, Opts); -clean(<<62, Rest/binary>>, Acc, Opts) -> clean(Rest, [62] ++ Acc, Opts); -clean(<<63, Rest/binary>>, Acc, Opts) -> clean(Rest, [63] ++ Acc, Opts); -clean(<<64, Rest/binary>>, Acc, Opts) -> clean(Rest, [64] ++ Acc, Opts); -clean(<<65, Rest/binary>>, Acc, Opts) -> clean(Rest, [65] ++ Acc, Opts); -clean(<<66, Rest/binary>>, Acc, Opts) -> clean(Rest, [66] ++ Acc, Opts); -clean(<<67, Rest/binary>>, Acc, Opts) -> clean(Rest, [67] ++ Acc, Opts); -clean(<<68, Rest/binary>>, Acc, Opts) -> clean(Rest, [68] ++ Acc, Opts); -clean(<<69, Rest/binary>>, Acc, Opts) -> clean(Rest, [69] ++ Acc, Opts); -clean(<<70, Rest/binary>>, Acc, Opts) -> clean(Rest, [70] ++ Acc, Opts); -clean(<<71, Rest/binary>>, Acc, Opts) -> clean(Rest, [71] ++ Acc, Opts); -clean(<<72, Rest/binary>>, Acc, Opts) -> clean(Rest, [72] ++ Acc, Opts); -clean(<<73, Rest/binary>>, Acc, Opts) -> clean(Rest, [73] ++ Acc, Opts); -clean(<<74, Rest/binary>>, Acc, Opts) -> clean(Rest, [74] ++ Acc, Opts); -clean(<<75, Rest/binary>>, Acc, Opts) -> clean(Rest, [75] ++ Acc, Opts); -clean(<<76, Rest/binary>>, Acc, Opts) -> clean(Rest, [76] ++ Acc, Opts); -clean(<<77, Rest/binary>>, Acc, Opts) -> clean(Rest, [77] ++ Acc, Opts); -clean(<<78, Rest/binary>>, Acc, Opts) -> clean(Rest, [78] ++ Acc, Opts); -clean(<<79, Rest/binary>>, Acc, Opts) -> clean(Rest, [79] ++ Acc, Opts); -clean(<<80, Rest/binary>>, Acc, Opts) -> clean(Rest, [80] ++ Acc, Opts); -clean(<<81, Rest/binary>>, Acc, Opts) -> clean(Rest, [81] ++ Acc, Opts); -clean(<<82, Rest/binary>>, Acc, Opts) -> clean(Rest, [82] ++ Acc, Opts); -clean(<<83, Rest/binary>>, Acc, Opts) -> clean(Rest, [83] ++ Acc, Opts); -clean(<<84, Rest/binary>>, Acc, Opts) -> clean(Rest, [84] ++ Acc, Opts); -clean(<<85, Rest/binary>>, Acc, Opts) -> clean(Rest, [85] ++ Acc, Opts); -clean(<<86, Rest/binary>>, Acc, Opts) -> clean(Rest, [86] ++ Acc, Opts); -clean(<<87, Rest/binary>>, Acc, Opts) -> clean(Rest, [87] ++ Acc, Opts); -clean(<<88, Rest/binary>>, Acc, Opts) -> clean(Rest, [88] ++ Acc, Opts); -clean(<<89, Rest/binary>>, Acc, Opts) -> clean(Rest, [89] ++ Acc, Opts); -clean(<<90, Rest/binary>>, Acc, Opts) -> clean(Rest, [90] ++ Acc, Opts); -clean(<<91, Rest/binary>>, Acc, Opts) -> clean(Rest, [91] ++ Acc, Opts); -clean(<<92, Rest/binary>>, Acc, Opts) -> clean(Rest, maybe_replace(92, Opts) ++ Acc, Opts); -clean(<<93, Rest/binary>>, Acc, Opts) -> clean(Rest, [93] ++ Acc, Opts); -clean(<<94, Rest/binary>>, Acc, Opts) -> clean(Rest, [94] ++ Acc, Opts); -clean(<<95, Rest/binary>>, Acc, Opts) -> clean(Rest, [95] ++ Acc, Opts); -clean(<<96, Rest/binary>>, Acc, Opts) -> clean(Rest, [96] ++ Acc, Opts); -clean(<<97, Rest/binary>>, Acc, Opts) -> clean(Rest, [97] ++ Acc, Opts); -clean(<<98, Rest/binary>>, Acc, Opts) -> clean(Rest, [98] ++ Acc, Opts); -clean(<<99, Rest/binary>>, Acc, Opts) -> clean(Rest, [99] ++ Acc, Opts); -clean(<<100, Rest/binary>>, Acc, Opts) -> clean(Rest, [100] ++ Acc, Opts); -clean(<<101, Rest/binary>>, Acc, Opts) -> clean(Rest, [101] ++ Acc, Opts); -clean(<<102, Rest/binary>>, Acc, Opts) -> clean(Rest, [102] ++ Acc, Opts); -clean(<<103, Rest/binary>>, Acc, Opts) -> clean(Rest, [103] ++ Acc, Opts); -clean(<<104, Rest/binary>>, Acc, Opts) -> clean(Rest, [104] ++ Acc, Opts); -clean(<<105, Rest/binary>>, Acc, Opts) -> clean(Rest, [105] ++ Acc, Opts); -clean(<<106, Rest/binary>>, Acc, Opts) -> clean(Rest, [106] ++ Acc, Opts); -clean(<<107, Rest/binary>>, Acc, Opts) -> clean(Rest, [107] ++ Acc, Opts); -clean(<<108, Rest/binary>>, Acc, Opts) -> clean(Rest, [108] ++ Acc, Opts); -clean(<<109, Rest/binary>>, Acc, Opts) -> clean(Rest, [109] ++ Acc, Opts); -clean(<<110, Rest/binary>>, Acc, Opts) -> clean(Rest, [110] ++ Acc, Opts); -clean(<<111, Rest/binary>>, Acc, Opts) -> clean(Rest, [111] ++ Acc, Opts); -clean(<<112, Rest/binary>>, Acc, Opts) -> clean(Rest, [112] ++ Acc, Opts); -clean(<<113, Rest/binary>>, Acc, Opts) -> clean(Rest, [113] ++ Acc, Opts); -clean(<<114, Rest/binary>>, Acc, Opts) -> clean(Rest, [114] ++ Acc, Opts); -clean(<<115, Rest/binary>>, Acc, Opts) -> clean(Rest, [115] ++ Acc, Opts); -clean(<<116, Rest/binary>>, Acc, Opts) -> clean(Rest, [116] ++ Acc, Opts); -clean(<<117, Rest/binary>>, Acc, Opts) -> clean(Rest, [117] ++ Acc, Opts); -clean(<<118, Rest/binary>>, Acc, Opts) -> clean(Rest, [118] ++ Acc, Opts); -clean(<<119, Rest/binary>>, Acc, Opts) -> clean(Rest, [119] ++ Acc, Opts); -clean(<<120, Rest/binary>>, Acc, Opts) -> clean(Rest, [120] ++ Acc, Opts); -clean(<<121, Rest/binary>>, Acc, Opts) -> clean(Rest, [121] ++ Acc, Opts); -clean(<<122, Rest/binary>>, Acc, Opts) -> clean(Rest, [122] ++ Acc, Opts); -clean(<<123, Rest/binary>>, Acc, Opts) -> clean(Rest, [123] ++ Acc, Opts); -clean(<<124, Rest/binary>>, Acc, Opts) -> clean(Rest, [124] ++ Acc, Opts); -clean(<<125, Rest/binary>>, Acc, Opts) -> clean(Rest, [125] ++ Acc, Opts); -clean(<<126, Rest/binary>>, Acc, Opts) -> clean(Rest, [126] ++ Acc, Opts); -clean(<<127, Rest/binary>>, Acc, Opts) -> clean(Rest, [127] ++ Acc, Opts); -clean(<>, Acc, Opts) when X < 16#800 -> - clean(Rest, [X] ++ Acc, Opts); -clean(<>, Acc, Opts) when X == 16#2028; X == 16#2029 -> - clean(Rest, maybe_replace(X, Opts) ++ Acc, Opts); -clean(<>, Acc, Opts) when X < 16#d800 -> - clean(Rest, [X] ++ Acc, Opts); -clean(<>, Acc, Opts) when X > 16#dfff, X < 16#fdd0 -> - clean(Rest, [X] ++ Acc, Opts); -clean(<>, Acc, Opts) when X > 16#fdef, X < 16#fffe -> - clean(Rest, [X] ++ Acc, Opts); -clean(<>, Acc, Opts) when X >= 16#10000, X < 16#1fffe -> - clean(Rest, [X] ++ Acc, Opts); -clean(<>, Acc, Opts) when X >= 16#20000, X < 16#2fffe -> - clean(Rest, [X] ++ Acc, Opts); -clean(<>, Acc, Opts) when X >= 16#30000, X < 16#3fffe -> - clean(Rest, [X] ++ Acc, Opts); -clean(<>, Acc, Opts) when X >= 16#40000, X < 16#4fffe -> - clean(Rest, [X] ++ Acc, Opts); -clean(<>, Acc, Opts) when X >= 16#50000, X < 16#5fffe -> - clean(Rest, [X] ++ Acc, Opts); -clean(<>, Acc, Opts) when X >= 16#60000, X < 16#6fffe -> - clean(Rest, [X] ++ Acc, Opts); -clean(<>, Acc, Opts) when X >= 16#70000, X < 16#7fffe -> - clean(Rest, [X] ++ Acc, Opts); -clean(<>, Acc, Opts) when X >= 16#80000, X < 16#8fffe -> - clean(Rest, [X] ++ Acc, Opts); -clean(<>, Acc, Opts) when X >= 16#90000, X < 16#9fffe -> - clean(Rest, [X] ++ Acc, Opts); -clean(<>, Acc, Opts) when X >= 16#a0000, X < 16#afffe -> - clean(Rest, [X] ++ Acc, Opts); -clean(<>, Acc, Opts) when X >= 16#b0000, X < 16#bfffe -> - clean(Rest, [X] ++ Acc, Opts); -clean(<>, Acc, Opts) when X >= 16#c0000, X < 16#cfffe -> - clean(Rest, [X] ++ Acc, Opts); -clean(<>, Acc, Opts) when X >= 16#d0000, X < 16#dfffe -> - clean(Rest, [X] ++ Acc, Opts); -clean(<>, Acc, Opts) when X >= 16#e0000, X < 16#efffe -> - clean(Rest, [X] ++ Acc, Opts); -clean(<>, Acc, Opts) when X >= 16#f0000, X < 16#ffffe -> - clean(Rest, [X] ++ Acc, Opts); -clean(<>, Acc, Opts) when X >= 16#100000, X < 16#10fffe -> - clean(Rest, [X] ++ Acc, Opts); +clean(<<>>, Acc, _Config) -> unicode:characters_to_binary(lists:reverse(Acc)); +clean(<<0, Rest/binary>>, Acc, Config) -> clean(Rest, maybe_replace(0, Config) ++ Acc, Config); +clean(<<1, Rest/binary>>, Acc, Config) -> clean(Rest, maybe_replace(1, Config) ++ Acc, Config); +clean(<<2, Rest/binary>>, Acc, Config) -> clean(Rest, maybe_replace(2, Config) ++ Acc, Config); +clean(<<3, Rest/binary>>, Acc, Config) -> clean(Rest, maybe_replace(3, Config) ++ Acc, Config); +clean(<<4, Rest/binary>>, Acc, Config) -> clean(Rest, maybe_replace(4, Config) ++ Acc, Config); +clean(<<5, Rest/binary>>, Acc, Config) -> clean(Rest, maybe_replace(5, Config) ++ Acc, Config); +clean(<<6, Rest/binary>>, Acc, Config) -> clean(Rest, maybe_replace(6, Config) ++ Acc, Config); +clean(<<7, Rest/binary>>, Acc, Config) -> clean(Rest, maybe_replace(7, Config) ++ Acc, Config); +clean(<<8, Rest/binary>>, Acc, Config) -> clean(Rest, maybe_replace(8, Config) ++ Acc, Config); +clean(<<9, Rest/binary>>, Acc, Config) -> clean(Rest, maybe_replace(9, Config) ++ Acc, Config); +clean(<<10, Rest/binary>>, Acc, Config) -> clean(Rest, maybe_replace(10, Config) ++ Acc, Config); +clean(<<11, Rest/binary>>, Acc, Config) -> clean(Rest, maybe_replace(11, Config) ++ Acc, Config); +clean(<<12, Rest/binary>>, Acc, Config) -> clean(Rest, maybe_replace(12, Config) ++ Acc, Config); +clean(<<13, Rest/binary>>, Acc, Config) -> clean(Rest, maybe_replace(13, Config) ++ Acc, Config); +clean(<<14, Rest/binary>>, Acc, Config) -> clean(Rest, maybe_replace(14, Config) ++ Acc, Config); +clean(<<15, Rest/binary>>, Acc, Config) -> clean(Rest, maybe_replace(15, Config) ++ Acc, Config); +clean(<<16, Rest/binary>>, Acc, Config) -> clean(Rest, maybe_replace(16, Config) ++ Acc, Config); +clean(<<17, Rest/binary>>, Acc, Config) -> clean(Rest, maybe_replace(17, Config) ++ Acc, Config); +clean(<<18, Rest/binary>>, Acc, Config) -> clean(Rest, maybe_replace(18, Config) ++ Acc, Config); +clean(<<19, Rest/binary>>, Acc, Config) -> clean(Rest, maybe_replace(19, Config) ++ Acc, Config); +clean(<<20, Rest/binary>>, Acc, Config) -> clean(Rest, maybe_replace(20, Config) ++ Acc, Config); +clean(<<21, Rest/binary>>, Acc, Config) -> clean(Rest, maybe_replace(21, Config) ++ Acc, Config); +clean(<<22, Rest/binary>>, Acc, Config) -> clean(Rest, maybe_replace(22, Config) ++ Acc, Config); +clean(<<23, Rest/binary>>, Acc, Config) -> clean(Rest, maybe_replace(23, Config) ++ Acc, Config); +clean(<<24, Rest/binary>>, Acc, Config) -> clean(Rest, maybe_replace(24, Config) ++ Acc, Config); +clean(<<25, Rest/binary>>, Acc, Config) -> clean(Rest, maybe_replace(25, Config) ++ Acc, Config); +clean(<<26, Rest/binary>>, Acc, Config) -> clean(Rest, maybe_replace(26, Config) ++ Acc, Config); +clean(<<27, Rest/binary>>, Acc, Config) -> clean(Rest, maybe_replace(27, Config) ++ Acc, Config); +clean(<<28, Rest/binary>>, Acc, Config) -> clean(Rest, maybe_replace(28, Config) ++ Acc, Config); +clean(<<29, Rest/binary>>, Acc, Config) -> clean(Rest, maybe_replace(29, Config) ++ Acc, Config); +clean(<<30, Rest/binary>>, Acc, Config) -> clean(Rest, maybe_replace(30, Config) ++ Acc, Config); +clean(<<31, Rest/binary>>, Acc, Config) -> clean(Rest, maybe_replace(31, Config) ++ Acc, Config); +clean(<<32, Rest/binary>>, Acc, Config) -> clean(Rest, [32] ++ Acc, Config); +clean(<<33, Rest/binary>>, Acc, Config) -> clean(Rest, [33] ++ Acc, Config); +clean(<<34, Rest/binary>>, Acc, Config) -> clean(Rest, maybe_replace(34, Config) ++ Acc, Config); +clean(<<35, Rest/binary>>, Acc, Config) -> clean(Rest, [35] ++ Acc, Config); +clean(<<36, Rest/binary>>, Acc, Config) -> clean(Rest, [36] ++ Acc, Config); +clean(<<37, Rest/binary>>, Acc, Config) -> clean(Rest, [37] ++ Acc, Config); +clean(<<38, Rest/binary>>, Acc, Config) -> clean(Rest, [38] ++ Acc, Config); +clean(<<39, Rest/binary>>, Acc, Config) -> clean(Rest, [39] ++ Acc, Config); +clean(<<40, Rest/binary>>, Acc, Config) -> clean(Rest, [40] ++ Acc, Config); +clean(<<41, Rest/binary>>, Acc, Config) -> clean(Rest, [41] ++ Acc, Config); +clean(<<42, Rest/binary>>, Acc, Config) -> clean(Rest, [42] ++ Acc, Config); +clean(<<43, Rest/binary>>, Acc, Config) -> clean(Rest, [43] ++ Acc, Config); +clean(<<44, Rest/binary>>, Acc, Config) -> clean(Rest, [44] ++ Acc, Config); +clean(<<45, Rest/binary>>, Acc, Config) -> clean(Rest, [45] ++ Acc, Config); +clean(<<46, Rest/binary>>, Acc, Config) -> clean(Rest, [46] ++ Acc, Config); +clean(<<47, Rest/binary>>, Acc, Config) -> clean(Rest, maybe_replace(47, Config) ++ Acc, Config); +clean(<<48, Rest/binary>>, Acc, Config) -> clean(Rest, [48] ++ Acc, Config); +clean(<<49, Rest/binary>>, Acc, Config) -> clean(Rest, [49] ++ Acc, Config); +clean(<<50, Rest/binary>>, Acc, Config) -> clean(Rest, [50] ++ Acc, Config); +clean(<<51, Rest/binary>>, Acc, Config) -> clean(Rest, [51] ++ Acc, Config); +clean(<<52, Rest/binary>>, Acc, Config) -> clean(Rest, [52] ++ Acc, Config); +clean(<<53, Rest/binary>>, Acc, Config) -> clean(Rest, [53] ++ Acc, Config); +clean(<<54, Rest/binary>>, Acc, Config) -> clean(Rest, [54] ++ Acc, Config); +clean(<<55, Rest/binary>>, Acc, Config) -> clean(Rest, [55] ++ Acc, Config); +clean(<<56, Rest/binary>>, Acc, Config) -> clean(Rest, [56] ++ Acc, Config); +clean(<<57, Rest/binary>>, Acc, Config) -> clean(Rest, [57] ++ Acc, Config); +clean(<<58, Rest/binary>>, Acc, Config) -> clean(Rest, [58] ++ Acc, Config); +clean(<<59, Rest/binary>>, Acc, Config) -> clean(Rest, [59] ++ Acc, Config); +clean(<<60, Rest/binary>>, Acc, Config) -> clean(Rest, [60] ++ Acc, Config); +clean(<<61, Rest/binary>>, Acc, Config) -> clean(Rest, [61] ++ Acc, Config); +clean(<<62, Rest/binary>>, Acc, Config) -> clean(Rest, [62] ++ Acc, Config); +clean(<<63, Rest/binary>>, Acc, Config) -> clean(Rest, [63] ++ Acc, Config); +clean(<<64, Rest/binary>>, Acc, Config) -> clean(Rest, [64] ++ Acc, Config); +clean(<<65, Rest/binary>>, Acc, Config) -> clean(Rest, [65] ++ Acc, Config); +clean(<<66, Rest/binary>>, Acc, Config) -> clean(Rest, [66] ++ Acc, Config); +clean(<<67, Rest/binary>>, Acc, Config) -> clean(Rest, [67] ++ Acc, Config); +clean(<<68, Rest/binary>>, Acc, Config) -> clean(Rest, [68] ++ Acc, Config); +clean(<<69, Rest/binary>>, Acc, Config) -> clean(Rest, [69] ++ Acc, Config); +clean(<<70, Rest/binary>>, Acc, Config) -> clean(Rest, [70] ++ Acc, Config); +clean(<<71, Rest/binary>>, Acc, Config) -> clean(Rest, [71] ++ Acc, Config); +clean(<<72, Rest/binary>>, Acc, Config) -> clean(Rest, [72] ++ Acc, Config); +clean(<<73, Rest/binary>>, Acc, Config) -> clean(Rest, [73] ++ Acc, Config); +clean(<<74, Rest/binary>>, Acc, Config) -> clean(Rest, [74] ++ Acc, Config); +clean(<<75, Rest/binary>>, Acc, Config) -> clean(Rest, [75] ++ Acc, Config); +clean(<<76, Rest/binary>>, Acc, Config) -> clean(Rest, [76] ++ Acc, Config); +clean(<<77, Rest/binary>>, Acc, Config) -> clean(Rest, [77] ++ Acc, Config); +clean(<<78, Rest/binary>>, Acc, Config) -> clean(Rest, [78] ++ Acc, Config); +clean(<<79, Rest/binary>>, Acc, Config) -> clean(Rest, [79] ++ Acc, Config); +clean(<<80, Rest/binary>>, Acc, Config) -> clean(Rest, [80] ++ Acc, Config); +clean(<<81, Rest/binary>>, Acc, Config) -> clean(Rest, [81] ++ Acc, Config); +clean(<<82, Rest/binary>>, Acc, Config) -> clean(Rest, [82] ++ Acc, Config); +clean(<<83, Rest/binary>>, Acc, Config) -> clean(Rest, [83] ++ Acc, Config); +clean(<<84, Rest/binary>>, Acc, Config) -> clean(Rest, [84] ++ Acc, Config); +clean(<<85, Rest/binary>>, Acc, Config) -> clean(Rest, [85] ++ Acc, Config); +clean(<<86, Rest/binary>>, Acc, Config) -> clean(Rest, [86] ++ Acc, Config); +clean(<<87, Rest/binary>>, Acc, Config) -> clean(Rest, [87] ++ Acc, Config); +clean(<<88, Rest/binary>>, Acc, Config) -> clean(Rest, [88] ++ Acc, Config); +clean(<<89, Rest/binary>>, Acc, Config) -> clean(Rest, [89] ++ Acc, Config); +clean(<<90, Rest/binary>>, Acc, Config) -> clean(Rest, [90] ++ Acc, Config); +clean(<<91, Rest/binary>>, Acc, Config) -> clean(Rest, [91] ++ Acc, Config); +clean(<<92, Rest/binary>>, Acc, Config) -> clean(Rest, maybe_replace(92, Config) ++ Acc, Config); +clean(<<93, Rest/binary>>, Acc, Config) -> clean(Rest, [93] ++ Acc, Config); +clean(<<94, Rest/binary>>, Acc, Config) -> clean(Rest, [94] ++ Acc, Config); +clean(<<95, Rest/binary>>, Acc, Config) -> clean(Rest, [95] ++ Acc, Config); +clean(<<96, Rest/binary>>, Acc, Config) -> clean(Rest, [96] ++ Acc, Config); +clean(<<97, Rest/binary>>, Acc, Config) -> clean(Rest, [97] ++ Acc, Config); +clean(<<98, Rest/binary>>, Acc, Config) -> clean(Rest, [98] ++ Acc, Config); +clean(<<99, Rest/binary>>, Acc, Config) -> clean(Rest, [99] ++ Acc, Config); +clean(<<100, Rest/binary>>, Acc, Config) -> clean(Rest, [100] ++ Acc, Config); +clean(<<101, Rest/binary>>, Acc, Config) -> clean(Rest, [101] ++ Acc, Config); +clean(<<102, Rest/binary>>, Acc, Config) -> clean(Rest, [102] ++ Acc, Config); +clean(<<103, Rest/binary>>, Acc, Config) -> clean(Rest, [103] ++ Acc, Config); +clean(<<104, Rest/binary>>, Acc, Config) -> clean(Rest, [104] ++ Acc, Config); +clean(<<105, Rest/binary>>, Acc, Config) -> clean(Rest, [105] ++ Acc, Config); +clean(<<106, Rest/binary>>, Acc, Config) -> clean(Rest, [106] ++ Acc, Config); +clean(<<107, Rest/binary>>, Acc, Config) -> clean(Rest, [107] ++ Acc, Config); +clean(<<108, Rest/binary>>, Acc, Config) -> clean(Rest, [108] ++ Acc, Config); +clean(<<109, Rest/binary>>, Acc, Config) -> clean(Rest, [109] ++ Acc, Config); +clean(<<110, Rest/binary>>, Acc, Config) -> clean(Rest, [110] ++ Acc, Config); +clean(<<111, Rest/binary>>, Acc, Config) -> clean(Rest, [111] ++ Acc, Config); +clean(<<112, Rest/binary>>, Acc, Config) -> clean(Rest, [112] ++ Acc, Config); +clean(<<113, Rest/binary>>, Acc, Config) -> clean(Rest, [113] ++ Acc, Config); +clean(<<114, Rest/binary>>, Acc, Config) -> clean(Rest, [114] ++ Acc, Config); +clean(<<115, Rest/binary>>, Acc, Config) -> clean(Rest, [115] ++ Acc, Config); +clean(<<116, Rest/binary>>, Acc, Config) -> clean(Rest, [116] ++ Acc, Config); +clean(<<117, Rest/binary>>, Acc, Config) -> clean(Rest, [117] ++ Acc, Config); +clean(<<118, Rest/binary>>, Acc, Config) -> clean(Rest, [118] ++ Acc, Config); +clean(<<119, Rest/binary>>, Acc, Config) -> clean(Rest, [119] ++ Acc, Config); +clean(<<120, Rest/binary>>, Acc, Config) -> clean(Rest, [120] ++ Acc, Config); +clean(<<121, Rest/binary>>, Acc, Config) -> clean(Rest, [121] ++ Acc, Config); +clean(<<122, Rest/binary>>, Acc, Config) -> clean(Rest, [122] ++ Acc, Config); +clean(<<123, Rest/binary>>, Acc, Config) -> clean(Rest, [123] ++ Acc, Config); +clean(<<124, Rest/binary>>, Acc, Config) -> clean(Rest, [124] ++ Acc, Config); +clean(<<125, Rest/binary>>, Acc, Config) -> clean(Rest, [125] ++ Acc, Config); +clean(<<126, Rest/binary>>, Acc, Config) -> clean(Rest, [126] ++ Acc, Config); +clean(<<127, Rest/binary>>, Acc, Config) -> clean(Rest, [127] ++ Acc, Config); +clean(<>, Acc, Config) when X < 16#800 -> + clean(Rest, [X] ++ Acc, Config); +clean(<>, Acc, Config) when X == 16#2028; X == 16#2029 -> + clean(Rest, maybe_replace(X, Config) ++ Acc, Config); +clean(<>, Acc, Config) when X < 16#d800 -> + clean(Rest, [X] ++ Acc, Config); +clean(<>, Acc, Config) when X > 16#dfff, X < 16#fdd0 -> + clean(Rest, [X] ++ Acc, Config); +clean(<>, Acc, Config) when X > 16#fdef, X < 16#fffe -> + clean(Rest, [X] ++ Acc, Config); +clean(<>, Acc, Config) when X >= 16#10000, X < 16#1fffe -> + clean(Rest, [X] ++ Acc, Config); +clean(<>, Acc, Config) when X >= 16#20000, X < 16#2fffe -> + clean(Rest, [X] ++ Acc, Config); +clean(<>, Acc, Config) when X >= 16#30000, X < 16#3fffe -> + clean(Rest, [X] ++ Acc, Config); +clean(<>, Acc, Config) when X >= 16#40000, X < 16#4fffe -> + clean(Rest, [X] ++ Acc, Config); +clean(<>, Acc, Config) when X >= 16#50000, X < 16#5fffe -> + clean(Rest, [X] ++ Acc, Config); +clean(<>, Acc, Config) when X >= 16#60000, X < 16#6fffe -> + clean(Rest, [X] ++ Acc, Config); +clean(<>, Acc, Config) when X >= 16#70000, X < 16#7fffe -> + clean(Rest, [X] ++ Acc, Config); +clean(<>, Acc, Config) when X >= 16#80000, X < 16#8fffe -> + clean(Rest, [X] ++ Acc, Config); +clean(<>, Acc, Config) when X >= 16#90000, X < 16#9fffe -> + clean(Rest, [X] ++ Acc, Config); +clean(<>, Acc, Config) when X >= 16#a0000, X < 16#afffe -> + clean(Rest, [X] ++ Acc, Config); +clean(<>, Acc, Config) when X >= 16#b0000, X < 16#bfffe -> + clean(Rest, [X] ++ Acc, Config); +clean(<>, Acc, Config) when X >= 16#c0000, X < 16#cfffe -> + clean(Rest, [X] ++ Acc, Config); +clean(<>, Acc, Config) when X >= 16#d0000, X < 16#dfffe -> + clean(Rest, [X] ++ Acc, Config); +clean(<>, Acc, Config) when X >= 16#e0000, X < 16#efffe -> + clean(Rest, [X] ++ Acc, Config); +clean(<>, Acc, Config) when X >= 16#f0000, X < 16#ffffe -> + clean(Rest, [X] ++ Acc, Config); +clean(<>, Acc, Config) when X >= 16#100000, X < 16#10fffe -> + clean(Rest, [X] ++ Acc, Config); %% noncharacters -clean(<<_/utf8, Rest/binary>>, Acc, Opts) -> - clean(Rest, maybe_replace(noncharacter, Opts) ++ Acc, Opts); +clean(<<_/utf8, Rest/binary>>, Acc, Config) -> + clean(Rest, maybe_replace(noncharacter, Config) ++ Acc, Config); %% surrogates -clean(<<237, X, _, Rest/binary>>, Acc, Opts) when X >= 160 -> - clean(Rest, maybe_replace(surrogate, Opts) ++ Acc, Opts); +clean(<<237, X, _, Rest/binary>>, Acc, Config) when X >= 160 -> + clean(Rest, maybe_replace(surrogate, Config) ++ Acc, Config); %% u+fffe and u+ffff for R14BXX -clean(<<239, 191, X, Rest/binary>>, Acc, Opts) when X == 190; X == 191 -> - clean(Rest, maybe_replace(noncharacter, Opts) ++ Acc, Opts); +clean(<<239, 191, X, Rest/binary>>, Acc, Config) when X == 190; X == 191 -> + clean(Rest, maybe_replace(noncharacter, Config) ++ Acc, Config); %% overlong encodings and missing continuations of a 2 byte sequence -clean(<>, Acc, Opts) when X >= 192, X =< 223 -> - clean(strip_continuations(Rest, 1), maybe_replace(badutf, Opts) ++ Acc, Opts); +clean(<>, Acc, Config) when X >= 192, X =< 223 -> + clean(strip_continuations(Rest, 1), maybe_replace(badutf, Config) ++ Acc, Config); %% overlong encodings and missing continuations of a 3 byte sequence -clean(<>, Acc, Opts) when X >= 224, X =< 239 -> - clean(strip_continuations(Rest, 2), maybe_replace(badutf, Opts) ++ Acc, Opts); +clean(<>, Acc, Config) when X >= 224, X =< 239 -> + clean(strip_continuations(Rest, 2), maybe_replace(badutf, Config) ++ Acc, Config); %% overlong encodings and missing continuations of a 4 byte sequence -clean(<>, Acc, Opts) when X >= 240, X =< 247 -> - clean(strip_continuations(Rest, 3), maybe_replace(badutf, Opts) ++ Acc, Opts); -clean(<<_, Rest/binary>>, Acc, Opts) -> - clean(Rest, maybe_replace(badutf, Opts) ++ Acc, Opts). +clean(<>, Acc, Config) when X >= 240, X =< 247 -> + clean(strip_continuations(Rest, 3), maybe_replace(badutf, Config) ++ Acc, Config); +clean(<<_, Rest/binary>>, Acc, Config) -> + clean(Rest, maybe_replace(badutf, Config) ++ Acc, Config). strip_continuations(Bin, 0) -> Bin; @@ -505,28 +505,28 @@ strip_continuations(<>, N) when X >= 128, X =< 191 -> strip_continuations(Bin, _) -> Bin. -maybe_replace($\b, #opts{escaped_strings=true}) -> [$b, $\\]; -maybe_replace($\t, #opts{escaped_strings=true}) -> [$t, $\\]; -maybe_replace($\n, #opts{escaped_strings=true}) -> [$n, $\\]; -maybe_replace($\f, #opts{escaped_strings=true}) -> [$f, $\\]; -maybe_replace($\r, #opts{escaped_strings=true}) -> [$r, $\\]; -maybe_replace($\", #opts{escaped_strings=true}) -> [$\", $\\]; -maybe_replace($\\, #opts{escaped_strings=true}) -> [$\\, $\\]; -maybe_replace($/, Opts) -> - case Opts#opts.escaped_forward_slashes of +maybe_replace($\b, #config{escaped_strings=true}) -> [$b, $\\]; +maybe_replace($\t, #config{escaped_strings=true}) -> [$t, $\\]; +maybe_replace($\n, #config{escaped_strings=true}) -> [$n, $\\]; +maybe_replace($\f, #config{escaped_strings=true}) -> [$f, $\\]; +maybe_replace($\r, #config{escaped_strings=true}) -> [$r, $\\]; +maybe_replace($\", #config{escaped_strings=true}) -> [$\", $\\]; +maybe_replace($\\, #config{escaped_strings=true}) -> [$\\, $\\]; +maybe_replace($/, Config) -> + case Config#config.escaped_forward_slashes of true -> [$/, $\\] ; false -> [$/] end; -maybe_replace(X, Opts=#opts{escaped_strings=true}) when X == 16#2028; X == 16#2029 -> - case Opts#opts.unescaped_jsonp of +maybe_replace(X, Config=#config{escaped_strings=true}) when X == 16#2028; X == 16#2029 -> + case Config#config.unescaped_jsonp of true -> [X] ; false -> lists:reverse(jsx_utils:json_escape_sequence(X)) end; -maybe_replace(X, #opts{escaped_strings=true}) when X < 32 -> +maybe_replace(X, #config{escaped_strings=true}) when X < 32 -> lists:reverse(jsx_utils:json_escape_sequence(X)); -maybe_replace(noncharacter, #opts{replaced_bad_utf8=true}) -> [16#fffd]; -maybe_replace(surrogate, #opts{replaced_bad_utf8=true}) -> [16#fffd]; -maybe_replace(badutf, #opts{replaced_bad_utf8=true}) -> [16#fffd]; +maybe_replace(noncharacter, #config{replaced_bad_utf8=true}) -> [16#fffd]; +maybe_replace(surrogate, #config{replaced_bad_utf8=true}) -> [16#fffd]; +maybe_replace(badutf, #config{replaced_bad_utf8=true}) -> [16#fffd]; maybe_replace(_, _) -> erlang:error(badarg). @@ -544,11 +544,11 @@ json_escape_sequence_test_() -> ]. -opts_test_() -> +config_test_() -> [ {"all flags", ?_assertEqual( - #opts{ + #config{ replaced_bad_utf8=true, escaped_forward_slashes=true, explicit_end=true, @@ -558,7 +558,7 @@ opts_test_() -> dirty_strings=true, ignored_bad_escapes=true }, - parse_opts([ + parse_config([ replaced_bad_utf8, escaped_forward_slashes, explicit_end, @@ -572,17 +572,17 @@ opts_test_() -> }, {"relax flag", ?_assertEqual( - #opts{ + #config{ replaced_bad_utf8=true, single_quoted_strings=true, comments=true, ignored_bad_escapes=true }, - parse_opts([relax]) + parse_config([relax]) ) }, {"deprecated flags", ?_assertEqual( - #opts{ + #config{ pre_encode=fun lists:length/1, replaced_bad_utf8=true, escaped_forward_slashes=true, @@ -591,7 +591,7 @@ opts_test_() -> escaped_strings=true, ignored_bad_escapes=true }, - parse_opts([ + parse_config([ {pre_encoder, fun lists:length/1}, loose_unicode, escape_forward_slash, @@ -602,17 +602,17 @@ opts_test_() -> ]) )}, {"pre_encode flag", ?_assertEqual( - #opts{pre_encode=fun lists:length/1}, - parse_opts([{pre_encode, fun lists:length/1}]) + #config{pre_encode=fun lists:length/1}, + parse_config([{pre_encode, fun lists:length/1}]) )}, {"two pre_encoders defined", ?_assertError( badarg, - parse_opts([ + parse_config([ {pre_encode, fun(_) -> true end}, {pre_encode, fun(_) -> false end} ]) )}, - {"bad option flag", ?_assertError(badarg, parse_opts([error]))} + {"bad option flag", ?_assertError(badarg, parse_config([error]))} ]. @@ -686,7 +686,7 @@ fail_clean(Codepoints, Title) -> {generator, fun() -> case Codepoints of [N|Rest] -> - [ {Title, ?_assertError(badarg, clean(N, [], #opts{}))} + [ {Title, ?_assertError(badarg, clean(N, [], #config{}))} | fail_clean(Rest, Title) ] ; [] -> [] @@ -697,7 +697,7 @@ fail_bad(Codepoints, Title) -> {generator, fun() -> case Codepoints of [N|Rest] -> - [ {Title, ?_assertError(badarg, clean(N, [], #opts{}))} + [ {Title, ?_assertError(badarg, clean(N, [], #config{}))} | fail_bad(Rest, Title) ] ; [] -> [] @@ -708,7 +708,7 @@ replace_bad(Codepoints, Title) -> {generator, fun() -> case Codepoints of [N|Rest] -> - [ {Title, ?_assertEqual(<<16#fffd/utf8>>, clean(N, [], #opts{replaced_bad_utf8=true}))} + [ {Title, ?_assertEqual(<<16#fffd/utf8>>, clean(N, [], #config{replaced_bad_utf8=true}))} | replace_bad(Rest, Title) ] ; [] -> [] @@ -732,12 +732,12 @@ clean_test_() -> [ {"basic codepoints", ?_assertEqual( codepoints(), - clean(codepoints(), [], #opts{}) + clean(codepoints(), [], #config{}) )}, fail_clean(escapables(), "escapables"), {"extended codepoints", ?_assertEqual( extended_codepoints(), - clean(extended_codepoints(), [], #opts{}) + clean(extended_codepoints(), [], #config{}) )}, fail_clean(noncharacters(), "noncharacters"), fail_clean(extended_noncharacters(), "extended noncharacters"), @@ -750,182 +750,182 @@ escape_test_() -> [ {"escape backspace", ?_assertEqual( <<"\\b">>, - clean_string(to_fake_utf8(16#0008), #opts{escaped_strings=true}) + clean_string(to_fake_utf8(16#0008), #config{escaped_strings=true}) )}, {"escape tab", ?_assertEqual( <<"\\t">>, - clean_string(to_fake_utf8(16#0009), #opts{escaped_strings=true}) + clean_string(to_fake_utf8(16#0009), #config{escaped_strings=true}) )}, {"escape newline", ?_assertEqual( <<"\\n">>, - clean_string(to_fake_utf8(16#000a), #opts{escaped_strings=true}) + clean_string(to_fake_utf8(16#000a), #config{escaped_strings=true}) )}, {"escape formfeed", ?_assertEqual( <<"\\f">>, - clean_string(to_fake_utf8(16#000c), #opts{escaped_strings=true}) + clean_string(to_fake_utf8(16#000c), #config{escaped_strings=true}) )}, {"escape carriage return", ?_assertEqual( <<"\\r">>, - clean_string(to_fake_utf8(16#000d), #opts{escaped_strings=true}) + clean_string(to_fake_utf8(16#000d), #config{escaped_strings=true}) )}, {"escape quote", ?_assertEqual( <<"\\\"">>, - clean_string(to_fake_utf8(16#0022), #opts{escaped_strings=true}) + clean_string(to_fake_utf8(16#0022), #config{escaped_strings=true}) )}, {"escape forward slash", ?_assertEqual( <<"\\/">>, - clean_string(to_fake_utf8(16#002f), #opts{escaped_strings=true, escaped_forward_slashes=true}) + clean_string(to_fake_utf8(16#002f), #config{escaped_strings=true, escaped_forward_slashes=true}) )}, {"do not escape forward slash", ?_assertEqual( <<"/">>, - clean_string(to_fake_utf8(16#002f), #opts{escaped_strings=true}) + clean_string(to_fake_utf8(16#002f), #config{escaped_strings=true}) )}, {"escape backslash", ?_assertEqual( <<"\\\\">>, - clean_string(to_fake_utf8(16#005c), #opts{escaped_strings=true}) + clean_string(to_fake_utf8(16#005c), #config{escaped_strings=true}) )}, {"escape jsonp (u2028)", ?_assertEqual( <<"\\u2028">>, - clean_string(to_fake_utf8(16#2028), #opts{escaped_strings=true}) + clean_string(to_fake_utf8(16#2028), #config{escaped_strings=true}) )}, {"do not escape jsonp (u2028)", ?_assertEqual( <<16#2028/utf8>>, - clean_string(to_fake_utf8(16#2028), #opts{escaped_strings=true, unescaped_jsonp=true}) + clean_string(to_fake_utf8(16#2028), #config{escaped_strings=true, unescaped_jsonp=true}) )}, {"escape jsonp (u2029)", ?_assertEqual( <<"\\u2029">>, - clean_string(to_fake_utf8(16#2029), #opts{escaped_strings=true}) + clean_string(to_fake_utf8(16#2029), #config{escaped_strings=true}) )}, {"do not escape jsonp (u2029)", ?_assertEqual( <<16#2029/utf8>>, - clean_string(to_fake_utf8(16#2029), #opts{escaped_strings=true, unescaped_jsonp=true}) + clean_string(to_fake_utf8(16#2029), #config{escaped_strings=true, unescaped_jsonp=true}) )}, {"dirty string", ?_assertEqual( <<"\n">>, - clean_string(to_fake_utf8(16#000a), #opts{escaped_strings=true, dirty_strings=true}) + clean_string(to_fake_utf8(16#000a), #config{escaped_strings=true, dirty_strings=true}) )}, {"escape u0000", ?_assertEqual( <<"\\u0000">>, - clean_string(to_fake_utf8(16#0000), #opts{escaped_strings=true}) + clean_string(to_fake_utf8(16#0000), #config{escaped_strings=true}) )}, {"escape u0001", ?_assertEqual( <<"\\u0001">>, - clean_string(to_fake_utf8(16#0001), #opts{escaped_strings=true}) + clean_string(to_fake_utf8(16#0001), #config{escaped_strings=true}) )}, {"escape u0002", ?_assertEqual( <<"\\u0002">>, - clean_string(to_fake_utf8(16#0002), #opts{escaped_strings=true}) + clean_string(to_fake_utf8(16#0002), #config{escaped_strings=true}) )}, {"escape u0003", ?_assertEqual( <<"\\u0003">>, - clean_string(to_fake_utf8(16#0003), #opts{escaped_strings=true}) + clean_string(to_fake_utf8(16#0003), #config{escaped_strings=true}) )}, {"escape u0004", ?_assertEqual( <<"\\u0004">>, - clean_string(to_fake_utf8(16#0004), #opts{escaped_strings=true}) + clean_string(to_fake_utf8(16#0004), #config{escaped_strings=true}) )}, {"escape u0005", ?_assertEqual( <<"\\u0005">>, - clean_string(to_fake_utf8(16#0005), #opts{escaped_strings=true}) + clean_string(to_fake_utf8(16#0005), #config{escaped_strings=true}) )}, {"escape u0006", ?_assertEqual( <<"\\u0006">>, - clean_string(to_fake_utf8(16#0006), #opts{escaped_strings=true}) + clean_string(to_fake_utf8(16#0006), #config{escaped_strings=true}) )}, {"escape u0007", ?_assertEqual( <<"\\u0007">>, - clean_string(to_fake_utf8(16#0007), #opts{escaped_strings=true}) + clean_string(to_fake_utf8(16#0007), #config{escaped_strings=true}) )}, {"escape u000b", ?_assertEqual( <<"\\u000b">>, - clean_string(to_fake_utf8(16#000b), #opts{escaped_strings=true}) + clean_string(to_fake_utf8(16#000b), #config{escaped_strings=true}) )}, {"escape u000e", ?_assertEqual( <<"\\u000e">>, - clean_string(to_fake_utf8(16#000e), #opts{escaped_strings=true}) + clean_string(to_fake_utf8(16#000e), #config{escaped_strings=true}) )}, {"escape u000f", ?_assertEqual( <<"\\u000f">>, - clean_string(to_fake_utf8(16#000f), #opts{escaped_strings=true}) + clean_string(to_fake_utf8(16#000f), #config{escaped_strings=true}) )}, {"escape u0010", ?_assertEqual( <<"\\u0010">>, - clean_string(to_fake_utf8(16#0010), #opts{escaped_strings=true}) + clean_string(to_fake_utf8(16#0010), #config{escaped_strings=true}) )}, {"escape u0011", ?_assertEqual( <<"\\u0011">>, - clean_string(to_fake_utf8(16#0011), #opts{escaped_strings=true}) + clean_string(to_fake_utf8(16#0011), #config{escaped_strings=true}) )}, {"escape u0012", ?_assertEqual( <<"\\u0012">>, - clean_string(to_fake_utf8(16#0012), #opts{escaped_strings=true}) + clean_string(to_fake_utf8(16#0012), #config{escaped_strings=true}) )}, {"escape u0013", ?_assertEqual( <<"\\u0013">>, - clean_string(to_fake_utf8(16#0013), #opts{escaped_strings=true}) + clean_string(to_fake_utf8(16#0013), #config{escaped_strings=true}) )}, {"escape u0014", ?_assertEqual( <<"\\u0014">>, - clean_string(to_fake_utf8(16#0014), #opts{escaped_strings=true}) + clean_string(to_fake_utf8(16#0014), #config{escaped_strings=true}) )}, {"escape u0015", ?_assertEqual( <<"\\u0015">>, - clean_string(to_fake_utf8(16#0015), #opts{escaped_strings=true}) + clean_string(to_fake_utf8(16#0015), #config{escaped_strings=true}) )}, {"escape u0016", ?_assertEqual( <<"\\u0016">>, - clean_string(to_fake_utf8(16#0016), #opts{escaped_strings=true}) + clean_string(to_fake_utf8(16#0016), #config{escaped_strings=true}) )}, {"escape u0017", ?_assertEqual( <<"\\u0017">>, - clean_string(to_fake_utf8(16#0017), #opts{escaped_strings=true}) + clean_string(to_fake_utf8(16#0017), #config{escaped_strings=true}) )}, {"escape u0018", ?_assertEqual( <<"\\u0018">>, - clean_string(to_fake_utf8(16#0018), #opts{escaped_strings=true}) + clean_string(to_fake_utf8(16#0018), #config{escaped_strings=true}) )}, {"escape u0019", ?_assertEqual( <<"\\u0019">>, - clean_string(to_fake_utf8(16#0019), #opts{escaped_strings=true}) + clean_string(to_fake_utf8(16#0019), #config{escaped_strings=true}) )}, {"escape u001a", ?_assertEqual( <<"\\u001a">>, - clean_string(to_fake_utf8(16#001a), #opts{escaped_strings=true}) + clean_string(to_fake_utf8(16#001a), #config{escaped_strings=true}) )}, {"escape u001b", ?_assertEqual( <<"\\u001b">>, - clean_string(to_fake_utf8(16#001b), #opts{escaped_strings=true}) + clean_string(to_fake_utf8(16#001b), #config{escaped_strings=true}) )}, {"escape u001c", ?_assertEqual( <<"\\u001c">>, - clean_string(to_fake_utf8(16#001c), #opts{escaped_strings=true}) + clean_string(to_fake_utf8(16#001c), #config{escaped_strings=true}) )}, {"escape u001d", ?_assertEqual( <<"\\u001d">>, - clean_string(to_fake_utf8(16#001d), #opts{escaped_strings=true}) + clean_string(to_fake_utf8(16#001d), #config{escaped_strings=true}) )}, {"escape u001e", ?_assertEqual( <<"\\u001e">>, - clean_string(to_fake_utf8(16#001e), #opts{escaped_strings=true}) + clean_string(to_fake_utf8(16#001e), #config{escaped_strings=true}) )}, {"escape u001f", ?_assertEqual( <<"\\u001f">>, - clean_string(to_fake_utf8(16#001f), #opts{escaped_strings=true}) + clean_string(to_fake_utf8(16#001f), #config{escaped_strings=true}) )} ]. bad_utf8_test_() -> [ - {"noncharacter u+fffe", ?_assertError(badarg, clean_string(to_fake_utf8(16#fffe), #opts{}))}, + {"noncharacter u+fffe", ?_assertError(badarg, clean_string(to_fake_utf8(16#fffe), #config{}))}, {"noncharacter u+fffe replaced", ?_assertEqual( <<16#fffd/utf8>>, - clean_string(to_fake_utf8(16#fffe), #opts{replaced_bad_utf8=true}) + clean_string(to_fake_utf8(16#fffe), #config{replaced_bad_utf8=true}) )}, - {"noncharacter u+ffff", ?_assertError(badarg, clean_string(to_fake_utf8(16#ffff), #opts{}))}, + {"noncharacter u+ffff", ?_assertError(badarg, clean_string(to_fake_utf8(16#ffff), #config{}))}, {"noncharacter u+ffff replaced", ?_assertEqual( <<16#fffd/utf8>>, - clean_string(to_fake_utf8(16#ffff), #opts{replaced_bad_utf8=true}) + clean_string(to_fake_utf8(16#ffff), #config{replaced_bad_utf8=true}) )}, fail_bad(extended_noncharacters(), "extended noncharacters"), replace_bad(extended_noncharacters(), "extended noncharacters replaced"), @@ -935,167 +935,167 @@ bad_utf8_test_() -> replace_bad(reserved_space(), "reserved space replaced"), {"orphan continuation byte u+0080", ?_assertError( badarg, - clean_string(<<16#0080>>, #opts{}) + clean_string(<<16#0080>>, #config{}) )}, {"orphan continuation byte u+0080 replaced", ?_assertEqual( <<16#fffd/utf8>>, - clean_string(<<16#0080>>, #opts{replaced_bad_utf8=true}) + clean_string(<<16#0080>>, #config{replaced_bad_utf8=true}) )}, {"orphan continuation byte u+00bf", ?_assertError( badarg, - clean_string(<<16#00bf>>, #opts{}) + clean_string(<<16#00bf>>, #config{}) )}, {"orphan continuation byte u+00bf replaced", ?_assertEqual( <<16#fffd/utf8>>, - clean_string(<<16#00bf>>, #opts{replaced_bad_utf8=true}) + clean_string(<<16#00bf>>, #config{replaced_bad_utf8=true}) )}, {"2 continuation bytes", ?_assertError( badarg, - clean_string(<<(binary:copy(<<16#0080>>, 2))/binary>>, #opts{}) + clean_string(<<(binary:copy(<<16#0080>>, 2))/binary>>, #config{}) )}, {"2 continuation bytes replaced", ?_assertEqual( binary:copy(<<16#fffd/utf8>>, 2), - clean_string(<<(binary:copy(<<16#0080>>, 2))/binary>>, #opts{replaced_bad_utf8=true}) + clean_string(<<(binary:copy(<<16#0080>>, 2))/binary>>, #config{replaced_bad_utf8=true}) )}, {"3 continuation bytes", - ?_assertError(badarg, clean_string(<<(binary:copy(<<16#0080>>, 3))/binary>>, #opts{})) + ?_assertError(badarg, clean_string(<<(binary:copy(<<16#0080>>, 3))/binary>>, #config{})) }, {"3 continuation bytes replaced", ?_assertEqual( binary:copy(<<16#fffd/utf8>>, 3), - clean_string(<<(binary:copy(<<16#0080>>, 3))/binary>>, #opts{replaced_bad_utf8=true}) + clean_string(<<(binary:copy(<<16#0080>>, 3))/binary>>, #config{replaced_bad_utf8=true}) )}, {"4 continuation bytes", - ?_assertError(badarg, clean_string(<<(binary:copy(<<16#0080>>, 4))/binary>>, #opts{})) + ?_assertError(badarg, clean_string(<<(binary:copy(<<16#0080>>, 4))/binary>>, #config{})) }, {"4 continuation bytes replaced", ?_assertEqual( binary:copy(<<16#fffd/utf8>>, 4), - clean_string(<<(binary:copy(<<16#0080>>, 4))/binary>>, #opts{replaced_bad_utf8=true}) + clean_string(<<(binary:copy(<<16#0080>>, 4))/binary>>, #config{replaced_bad_utf8=true}) )}, {"5 continuation bytes", - ?_assertError(badarg, clean_string(<<(binary:copy(<<16#0080>>, 5))/binary>>, #opts{})) + ?_assertError(badarg, clean_string(<<(binary:copy(<<16#0080>>, 5))/binary>>, #config{})) }, {"5 continuation bytes replaced", ?_assertEqual( binary:copy(<<16#fffd/utf8>>, 5), - clean_string(<<(binary:copy(<<16#0080>>, 5))/binary>>, #opts{replaced_bad_utf8=true}) + clean_string(<<(binary:copy(<<16#0080>>, 5))/binary>>, #config{replaced_bad_utf8=true}) )}, {"6 continuation bytes", - ?_assertError(badarg, clean_string(<<(binary:copy(<<16#0080>>, 6))/binary>>, #opts{})) + ?_assertError(badarg, clean_string(<<(binary:copy(<<16#0080>>, 6))/binary>>, #config{})) }, {"6 continuation bytes replaced", ?_assertEqual( binary:copy(<<16#fffd/utf8>>, 6), - clean_string(<<(binary:copy(<<16#0080>>, 6))/binary>>, #opts{replaced_bad_utf8=true}) + clean_string(<<(binary:copy(<<16#0080>>, 6))/binary>>, #config{replaced_bad_utf8=true}) )}, {"all continuation bytes", ?_assertError( badarg, - clean_string(<<(list_to_binary(lists:seq(16#0080, 16#00bf)))/binary>>, #opts{}) + clean_string(<<(list_to_binary(lists:seq(16#0080, 16#00bf)))/binary>>, #config{}) )}, {"all continuation bytes replaced", ?_assertEqual( binary:copy(<<16#fffd/utf8>>, length(lists:seq(16#0080, 16#00bf))), clean_string( <<(list_to_binary(lists:seq(16#0080, 16#00bf)))/binary>>, - #opts{replaced_bad_utf8=true} + #config{replaced_bad_utf8=true} ) )}, - {"lonely start byte", ?_assertError(badarg, clean_string(<<16#00c0>>, #opts{}))}, + {"lonely start byte", ?_assertError(badarg, clean_string(<<16#00c0>>, #config{}))}, {"lonely start byte replaced", ?_assertEqual( <<16#fffd/utf8>>, - clean_string(<<16#00c0>>, #opts{replaced_bad_utf8=true}) + clean_string(<<16#00c0>>, #config{replaced_bad_utf8=true}) )}, {"lonely start bytes (2 byte)", ?_assertError( badarg, - clean_string(<<16#00c0, 32, 16#00df>>, #opts{}) + clean_string(<<16#00c0, 32, 16#00df>>, #config{}) )}, {"lonely start bytes (2 byte) replaced", ?_assertEqual( <<16#fffd/utf8, 32, 16#fffd/utf8>>, - clean_string(<<16#00c0, 32, 16#00df>>, #opts{replaced_bad_utf8=true}) + clean_string(<<16#00c0, 32, 16#00df>>, #config{replaced_bad_utf8=true}) )}, {"lonely start bytes (3 byte)", ?_assertError( badarg, - clean_string(<<16#00e0, 32, 16#00ef>>, #opts{}) + clean_string(<<16#00e0, 32, 16#00ef>>, #config{}) )}, {"lonely start bytes (3 byte) replaced", ?_assertEqual( <<16#fffd/utf8, 32, 16#fffd/utf8>>, - clean_string(<<16#00e0, 32, 16#00ef>>, #opts{replaced_bad_utf8=true}) + clean_string(<<16#00e0, 32, 16#00ef>>, #config{replaced_bad_utf8=true}) )}, {"lonely start bytes (4 byte)", ?_assertError( badarg, - clean_string(<<16#00f0, 32, 16#00f7>>, #opts{}) + clean_string(<<16#00f0, 32, 16#00f7>>, #config{}) )}, {"lonely start bytes (4 byte) replaced", ?_assertEqual( <<16#fffd/utf8, 32, 16#fffd/utf8>>, - clean_string(<<16#00f0, 32, 16#00f7>>, #opts{replaced_bad_utf8=true}) + clean_string(<<16#00f0, 32, 16#00f7>>, #config{replaced_bad_utf8=true}) )}, {"missing continuation byte (3 byte)", ?_assertError( badarg, - clean_string(<<224, 160, 32>>, #opts{}) + clean_string(<<224, 160, 32>>, #config{}) )}, {"missing continuation byte (3 byte) replaced", ?_assertEqual( <<16#fffd/utf8, 32>>, - clean_string(<<224, 160, 32>>, #opts{replaced_bad_utf8=true}) + clean_string(<<224, 160, 32>>, #config{replaced_bad_utf8=true}) )}, {"missing continuation byte (4 byte missing one)", ?_assertError( badarg, - clean_string(<<240, 144, 128, 32>>, #opts{}) + clean_string(<<240, 144, 128, 32>>, #config{}) )}, {"missing continuation byte (4 byte missing one) replaced", ?_assertEqual( <<16#fffd/utf8, 32>>, - clean_string(<<240, 144, 128, 32>>, #opts{replaced_bad_utf8=true}) + clean_string(<<240, 144, 128, 32>>, #config{replaced_bad_utf8=true}) )}, {"missing continuation byte (4 byte missing two)", ?_assertError( badarg, - clean_string(<<240, 144, 32>>, #opts{}) + clean_string(<<240, 144, 32>>, #config{}) )}, {"missing continuation byte (4 byte missing two) replaced", ?_assertEqual( <<16#fffd/utf8, 32>>, - clean_string(<<240, 144, 32>>, #opts{replaced_bad_utf8=true}) + clean_string(<<240, 144, 32>>, #config{replaced_bad_utf8=true}) )}, {"overlong encoding of u+002f (2 byte)", ?_assertError( badarg, - clean_string(<<16#c0, 16#af, 32>>, #opts{}) + clean_string(<<16#c0, 16#af, 32>>, #config{}) )}, {"overlong encoding of u+002f (2 byte) replaced", ?_assertEqual( <<16#fffd/utf8, 32>>, - clean_string(<<16#c0, 16#af, 32>>, #opts{replaced_bad_utf8=true}) + clean_string(<<16#c0, 16#af, 32>>, #config{replaced_bad_utf8=true}) )}, {"overlong encoding of u+002f (3 byte)", ?_assertError( badarg, - clean_string(<<16#e0, 16#80, 16#af, 32>>, #opts{}) + clean_string(<<16#e0, 16#80, 16#af, 32>>, #config{}) )}, {"overlong encoding of u+002f (3 byte) replaced", ?_assertEqual( <<16#fffd/utf8, 32>>, - clean_string(<<16#e0, 16#80, 16#af, 32>>, #opts{replaced_bad_utf8=true}) + clean_string(<<16#e0, 16#80, 16#af, 32>>, #config{replaced_bad_utf8=true}) )}, {"overlong encoding of u+002f (4 byte)", ?_assertError( badarg, - clean_string(<<16#f0, 16#80, 16#80, 16#af, 32>>, #opts{}) + clean_string(<<16#f0, 16#80, 16#80, 16#af, 32>>, #config{}) )}, {"overlong encoding of u+002f (4 byte) replaced", ?_assertEqual( <<16#fffd/utf8, 32>>, - clean_string(<<16#f0, 16#80, 16#80, 16#af, 32>>, #opts{replaced_bad_utf8=true}) + clean_string(<<16#f0, 16#80, 16#80, 16#af, 32>>, #config{replaced_bad_utf8=true}) )}, {"highest overlong 2 byte sequence", ?_assertError( badarg, - clean_string(<<16#c1, 16#bf, 32>>, #opts{}) + clean_string(<<16#c1, 16#bf, 32>>, #config{}) )}, {"highest overlong 2 byte sequence replaced", ?_assertEqual( <<16#fffd/utf8, 32>>, - clean_string(<<16#c1, 16#bf, 32>>, #opts{replaced_bad_utf8=true}) + clean_string(<<16#c1, 16#bf, 32>>, #config{replaced_bad_utf8=true}) )}, {"highest overlong 3 byte sequence", ?_assertError( badarg, - clean_string(<<16#e0, 16#9f, 16#bf, 32>>, #opts{}) + clean_string(<<16#e0, 16#9f, 16#bf, 32>>, #config{}) )}, {"highest overlong 3 byte sequence replaced", ?_assertEqual( <<16#fffd/utf8, 32>>, - clean_string(<<16#e0, 16#9f, 16#bf, 32>>, #opts{replaced_bad_utf8=true}) + clean_string(<<16#e0, 16#9f, 16#bf, 32>>, #config{replaced_bad_utf8=true}) )}, {"highest overlong 4 byte sequence", ?_assertError( badarg, - clean_string(<<16#f0, 16#8f, 16#bf, 16#bf, 32>>, #opts{}) + clean_string(<<16#f0, 16#8f, 16#bf, 16#bf, 32>>, #config{}) )}, {"highest overlong 4 byte sequence replaced", ?_assertEqual( <<16#fffd/utf8, 32>>, - clean_string(<<16#f0, 16#8f, 16#bf, 16#bf, 32>>, #opts{replaced_bad_utf8=true}) + clean_string(<<16#f0, 16#8f, 16#bf, 16#bf, 32>>, #config{replaced_bad_utf8=true}) )} ]. diff --git a/src/jsx_verify.erl b/src/jsx_verify.erl index 304807e..4818998 100644 --- a/src/jsx_verify.erl +++ b/src/jsx_verify.erl @@ -27,65 +27,65 @@ -export([init/1, handle_event/2]). --record(opts, { +-record(config, { repeated_keys = true }). --type opts() :: []. +-type config() :: []. --spec is_json(Source::binary(), Opts::opts()) -> true | false. +-spec is_json(Source::binary(), Config::config()) -> true | false. -is_json(Source, Opts) when is_list(Opts) -> - try (jsx:decoder(?MODULE, Opts, jsx_utils:extract_opts(Opts)))(Source) +is_json(Source, Config) when is_list(Config) -> + try (jsx:decoder(?MODULE, Config, jsx_utils:extract_config(Config)))(Source) catch error:badarg -> false end. --spec is_term(Source::any(), Opts::opts()) -> true | false. +-spec is_term(Source::any(), Config::config()) -> true | false. -is_term(Source, Opts) when is_list(Opts) -> - try (jsx:encoder(?MODULE, Opts, jsx_utils:extract_opts(Opts)))(Source) +is_term(Source, Config) when is_list(Config) -> + try (jsx:encoder(?MODULE, Config, jsx_utils:extract_config(Config)))(Source) catch error:badarg -> false end. -parse_opts(Opts) -> parse_opts(Opts, #opts{}). +parse_config(Config) -> parse_config(Config, #config{}). -parse_opts([{repeated_keys, Val}|Rest], Opts) when Val == true; Val == false -> - parse_opts(Rest, Opts#opts{repeated_keys = Val}); -parse_opts([repeated_keys|Rest], Opts) -> - parse_opts(Rest, Opts#opts{repeated_keys = true}); -parse_opts([{K, _}|Rest] = Options, Opts) -> +parse_config([{repeated_keys, Val}|Rest], Config) when Val == true; Val == false -> + parse_config(Rest, Config#config{repeated_keys = Val}); +parse_config([repeated_keys|Rest], Config) -> + parse_config(Rest, Config#config{repeated_keys = true}); +parse_config([{K, _}|Rest] = Options, Config) -> case lists:member(K, jsx_utils:valid_flags()) of - true -> parse_opts(Rest, Opts) - ; false -> erlang:error(badarg, [Options, Opts]) + true -> parse_config(Rest, Config) + ; false -> erlang:error(badarg, [Options, Config]) end; -parse_opts([K|Rest] = Options, Opts) -> +parse_config([K|Rest] = Options, Config) -> case lists:member(K, jsx_utils:valid_flags()) of - true -> parse_opts(Rest, Opts) - ; false -> erlang:error(badarg, [Options, Opts]) + true -> parse_config(Rest, Config) + ; false -> erlang:error(badarg, [Options, Config]) end; -parse_opts([], Opts) -> - Opts. +parse_config([], Config) -> + Config. -init(Opts) -> {parse_opts(Opts), []}. +init(Config) -> {parse_config(Config), []}. handle_event(end_json, _) -> true; -handle_event(_, {Opts, _} = State) when Opts#opts.repeated_keys == true -> State; +handle_event(_, {Config, _} = State) when Config#config.repeated_keys == true -> State; -handle_event(start_object, {Opts, Keys}) -> {Opts, [dict:new()] ++ Keys}; -handle_event(end_object, {Opts, [_|Keys]}) -> {Opts, Keys}; +handle_event(start_object, {Config, Keys}) -> {Config, [dict:new()] ++ Keys}; +handle_event(end_object, {Config, [_|Keys]}) -> {Config, Keys}; -handle_event({key, Key}, {Opts, [CurrentKeys|Keys]}) -> +handle_event({key, Key}, {Config, [CurrentKeys|Keys]}) -> case dict:is_key(Key, CurrentKeys) of true -> erlang:error(badarg) - ; false -> {Opts, [dict:store(Key, blah, CurrentKeys)|Keys]} + ; false -> {Config, [dict:store(Key, blah, CurrentKeys)|Keys]} end; handle_event(_, State) -> State. @@ -97,20 +97,20 @@ handle_event(_, State) -> State. -include_lib("eunit/include/eunit.hrl"). -opts_test_() -> +config_test_() -> [ - {"empty opts", ?_assertEqual(#opts{}, parse_opts([]))}, - {"bare repeated keys", ?_assertEqual(#opts{}, parse_opts([repeated_keys]))}, + {"empty config", ?_assertEqual(#config{}, parse_config([]))}, + {"bare repeated keys", ?_assertEqual(#config{}, parse_config([repeated_keys]))}, {"repeated keys true", ?_assertEqual( - #opts{}, - parse_opts([{repeated_keys, true}]) + #config{}, + parse_config([{repeated_keys, true}]) )}, {"repeated keys false", ?_assertEqual( - #opts{repeated_keys=false}, - parse_opts([{repeated_keys, false}]) + #config{repeated_keys=false}, + parse_config([{repeated_keys, false}]) )}, - {"invalid opt flag", ?_assertError(badarg, parse_opts([error]))}, - {"invalid opt tuple", ?_assertError(badarg, parse_opts([{error, true}]))} + {"invalid opt flag", ?_assertError(badarg, parse_config([error]))}, + {"invalid opt tuple", ?_assertError(badarg, parse_config([{error, true}]))} ]. @@ -121,7 +121,7 @@ handle_event_test_() -> { Title, ?_assertEqual( true, - lists:foldl(fun handle_event/2, {#opts{}, []}, Events ++ [end_json]) + lists:foldl(fun handle_event/2, {#config{}, []}, Events ++ [end_json]) ) } || {Title, _, _, Events} <- Data ].