diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..e154e2d8 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,86 @@ +name: ci + +on: + workflow_dispatch: + push: + branches: + - master + pull_request: + branches: + - master + +jobs: + linux: + name: ${{matrix.os}}-${{matrix.otp_version}}-${{matrix.rebar}} + runs-on: ${{matrix.os}} + + strategy: + fail-fast: false + matrix: + otp_version: [20,23,26,27] + os: [ubuntu-latest] + rebar: [rebar, rebar3] + + container: + image: erlang:${{matrix.otp_version}} + + steps: + - uses: actions/checkout@v4 + - name: ${{matrix.rebar}} make check + run: | + make REBAR=${{matrix.rebar}} check + + macos: + name: macos + runs-on: ${{matrix.os}} + + strategy: + fail-fast: false + matrix: + os: [macos-12, macos-14] + + steps: + - uses: actions/checkout@v4 + - name: install erlang + run: | + brew install erlang + - name: install rebar3 + run: | + brew install rebar3 + - name: make check + run: | + make check + + windows: + name: windows + runs-on: ${{matrix.os}} + + strategy: + fail-fast: false + matrix: + os: [windows-2019, windows-2022] + + steps: + - name: prevent git from messing up our json test files + run: | + git config --global core.autocrlf false + git config --global core.eol lf + - uses: actions/checkout@v4 + - name: install erlang + run: | + choco install erlang + - name: install rebar3 + run: | + choco install rebar3 + - name: make check + run: | + $path = vswhere -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -nologo -nocolor -property installationPath + if ($path) { + $path = join-path $path '\VC\Auxiliary\Build\vcvars64.bat' + if (test-path $path) { + cmd /s /c """$path"" $args && set" | where { $_ -match '(\w+)=(.*)' } | foreach { + $null = new-item -force -path "Env:\$($Matches[1])" -value $Matches[2] + } + } + } + make check diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 53bb22d9..00000000 --- a/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -language: erlang -notifications: - email: paul.joseph.davis@gmail.com -script: make check -otp_release: - - 23.0 - - 22.2.4 - - 21.3.8.1 - - 20.3.8.22 - - 19.3 - - 18.3 - - 17.5 - - R16B03-1 diff --git a/c_src/decoder.c b/c_src/decoder.c index 8f78117c..27d101a4 100644 --- a/c_src/decoder.c +++ b/c_src/decoder.c @@ -621,11 +621,9 @@ dec_number(Decoder* d, ERL_NIF_TERM* value) ERL_NIF_TERM make_empty_object(ErlNifEnv* env, int ret_map) { -#if MAP_TYPE_PRESENT if(ret_map) { return enif_make_new_map(env); } -#endif return enif_make_tuple1(env, enif_make_list(env, 0)); } @@ -680,11 +678,7 @@ decode_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) } else if(get_bytes_per_red(env, val, &(d->bytes_per_red))) { continue; } else if(enif_is_identical(val, d->atoms->atom_return_maps)) { -#if MAP_TYPE_PRESENT d->return_maps = 1; -#else - return enif_make_badarg(env); -#endif } else if(enif_is_identical(val, d->atoms->atom_return_trailer)) { d->return_trailer = 1; } else if(enif_is_identical(val, d->atoms->atom_dedupe_keys)) { diff --git a/c_src/encoder.c b/c_src/encoder.c index 4cfb3533..03c5500f 100644 --- a/c_src/encoder.c +++ b/c_src/encoder.c @@ -595,7 +595,6 @@ enc_comma(Encoder* e) return 1; } -#if MAP_TYPE_PRESENT int enc_map_to_ejson(ErlNifEnv* env, ERL_NIF_TERM map, ERL_NIF_TERM* out) { @@ -636,7 +635,6 @@ enc_map_to_ejson(ErlNifEnv* env, ERL_NIF_TERM map, ERL_NIF_TERM* out) *out = enif_make_tuple1(env, list); return 1; } -#endif ERL_NIF_TERM encode_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) @@ -897,7 +895,6 @@ encode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) termstack_push(&stack, curr); termstack_push(&stack, e->atoms->ref_object); termstack_push(&stack, tuple[1]); -#if MAP_TYPE_PRESENT } else if(enif_is_map(env, curr)) { if(!enc_map_to_ejson(env, curr, &curr)) { ret = enc_error(e, "internal_error"); @@ -905,7 +902,6 @@ encode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) } termstack_push(&stack, curr); -#endif } else if(enif_is_list(env, curr)) { if(!enc_start_array(e)) { ret = enc_error(e, "internal_error"); diff --git a/c_src/jiffy.h b/c_src/jiffy.h index 9c97945d..db426116 100644 --- a/c_src/jiffy.h +++ b/c_src/jiffy.h @@ -9,10 +9,6 @@ #define DEFAULT_BYTES_PER_REDUCTION 20 #define DEFAULT_ERLANG_REDUCTION_COUNT 2000 -#define MAP_TYPE_PRESENT \ - ((ERL_NIF_MAJOR_VERSION == 2 && ERL_NIF_MINOR_VERSION >= 6) \ - || (ERL_NIF_MAJOR_VERSION > 2)) - #define CONSUME_TIMESLICE_PRESENT \ ((ERL_NIF_MAJOR_VERSION >= 2 && ERL_NIF_MINOR_VERSION >= 4)) diff --git a/c_src/objects.cc b/c_src/objects.cc index 1a16699c..2a35b251 100644 --- a/c_src/objects.cc +++ b/c_src/objects.cc @@ -8,10 +8,6 @@ #include "erl_nif.h" -#define MAP_TYPE_PRESENT \ - ((ERL_NIF_MAJOR_VERSION == 2 && ERL_NIF_MINOR_VERSION >= 6) \ - || (ERL_NIF_MAJOR_VERSION > 2)) - #define BEGIN_C extern "C" { #define END_C } @@ -27,8 +23,6 @@ make_object(ErlNifEnv* env, ERL_NIF_TERM pairs, ERL_NIF_TERM* out, std::set seen; -#if MAP_TYPE_PRESENT - ERL_NIF_TERM old_val; if(ret_map) { @@ -46,7 +40,6 @@ make_object(ErlNifEnv* env, ERL_NIF_TERM pairs, ERL_NIF_TERM* out, *out = ret; return 1; } -#endif ret = enif_make_list(env, 0); while(enif_get_list_cell(env, pairs, &val, &pairs)) { diff --git a/rebar.config b/rebar.config index 0ee14f41..15e69b61 100644 --- a/rebar.config +++ b/rebar.config @@ -21,21 +21,9 @@ {"(linux|solaris|freebsd|netbsd|openbsd|dragonfly|darwin|gnu)", "LDFLAGS", "$LDFLAGS $FLTO_FLAG -lstdc++"}, - %% OS X Leopard flags for 64-bit - {"darwin9.*-64$", "CXXFLAGS", "-m64"}, - {"darwin9.*-64$", "LDFLAGS", "-arch x86_64"}, - - %% OS X Snow Leopard flags for 32-bit - {"darwin10.*-32$", "CXXFLAGS", "-m32"}, - {"darwin10.*-32$", "LDFLAGS", "-arch i386"}, - {"win32", "CXXFLAGS", "$CXXFLAGS /O2 /DNDEBUG"} ]}. -{erl_opts, [ - {platform_define, "R1(1|2|3|4|5|6)", 'JIFFY_NO_MAPS'} -]}. - {eunit_opts, [ verbose ]}. diff --git a/rebar.config.script b/rebar.config.script index 007e9b3e..c2f1689e 100644 --- a/rebar.config.script +++ b/rebar.config.script @@ -53,8 +53,11 @@ case IsRebar2 of Config2; false -> Config2 ++ [ - {plugins, [{pc, "~> 1.0"}]}, - {artifacts, ["priv/jiffy.so"]}, + {plugins, [{pc, "~> 1.15"}]}, + case os:type() of + {win32, _} -> {artifacts, ["priv/jiffy.dll"]}; + {_, _} -> {artifacts, ["priv/jiffy.so"]} + end, {provider_hooks, [ {post, [ {compile, {pc, compile}}, diff --git a/src/jiffy.erl b/src/jiffy.erl index 6af15b5f..b1f3b98a 100644 --- a/src/jiffy.erl +++ b/src/jiffy.erl @@ -22,17 +22,9 @@ -type json_string() :: atom() | binary(). -type json_number() :: integer() | float(). --ifdef(JIFFY_NO_MAPS). - --type json_object() :: {[{json_string(),json_value()}]}. - --else. - -type json_object() :: {[{json_string(),json_value()}]} | #{json_string() => json_value()}. --endif. - -type jiffy_decode_result() :: json_value() | {has_trailer, json_value(), binary()}. @@ -141,7 +133,6 @@ finish_decode({has_trailer, Value, Rest}) -> finish_decode(Val) -> maybe_map(Val). --ifndef(JIFFY_NO_MAPS). maybe_map(Obj) when is_map(Obj) -> maps:map(fun finish_decode_map/2, Obj); maybe_map(Val) -> @@ -149,10 +140,6 @@ maybe_map(Val) -> finish_decode_map(_, V) -> finish_decode(V). --else. -maybe_map(Val) -> - Val. --endif. finish_decode_obj([], Acc) -> {lists:reverse(Acc)}; diff --git a/src/jiffy_utf8.erl b/src/jiffy_utf8.erl index e79756f9..81346cbb 100644 --- a/src/jiffy_utf8.erl +++ b/src/jiffy_utf8.erl @@ -14,7 +14,6 @@ fix(Bin) when is_binary(Bin) -> fix(Val) -> maybe_map(Val). --ifndef(JIFFY_NO_MAPS). maybe_map(Obj) when is_map(Obj) -> maps:fold(fun fix_map/3, maps:new(), Obj); maybe_map(Val) -> @@ -22,10 +21,6 @@ maybe_map(Val) -> fix_map(K, V, Acc) -> maps:put(fix(K), fix(V), Acc). --else. -maybe_map(Val) -> - Val. --endif. fix_props([], Acc) -> {lists:reverse(Acc)}; diff --git a/test/jiffy_03_number_tests.erl b/test/jiffy_03_number_tests.erl index ad86a000..7ae8404c 100644 --- a/test/jiffy_03_number_tests.erl +++ b/test/jiffy_03_number_tests.erl @@ -36,8 +36,8 @@ gen(error, J) -> gen(floats, F) -> NegF = -1.0 * F, {msg("float round trip - ~p", [F]), [ - {"Pos", ?_assertEqual(F, dec(enc(F)))}, - {"Neg", ?_assertEqual(NegF, dec(enc(NegF)))} + {"Pos", ?_assert(F == dec(enc(F)))}, + {"Neg", ?_assert(NegF == dec(enc(NegF)))} ]}. diff --git a/test/jiffy_11_property_tests.erl b/test/jiffy_11_property_tests.erl index eb7cf934..b3f05a75 100644 --- a/test/jiffy_11_property_tests.erl +++ b/test/jiffy_11_property_tests.erl @@ -21,20 +21,9 @@ property_test_() -> run(prop_dec_trailer), run(prop_enc_no_crash), run(prop_dec_no_crash_bin), - run(prop_dec_no_crash_any) - ] ++ map_props(). - - --ifndef(JIFFY_NO_MAPS). -map_props() -> - [ + run(prop_dec_no_crash_any), run(prop_map_enc_dec) ]. --else. -map_props() -> - []. --endif. - prop_enc_dec() -> ?FORALL(Data, json(), begin @@ -63,7 +52,6 @@ prop_enc_dec_pretty() -> ). --ifndef(JIFFY_NO_MAPS). prop_map_enc_dec() -> ?FORALL(Data, json(), begin @@ -71,7 +59,6 @@ prop_map_enc_dec() -> MapData == jiffy:decode(jiffy:encode(MapData), [return_maps]) end ). --endif. prop_enc_no_crash() -> @@ -115,7 +102,6 @@ run(Name) -> ]}. --ifndef(JIFFY_NO_MAPS). to_map_ejson({Props}) -> NewProps = [{K, to_map_ejson(V)} || {K, V} <- Props], maps:from_list(NewProps); @@ -123,7 +109,6 @@ to_map_ejson(Vals) when is_list(Vals) -> [to_map_ejson(V) || V <- Vals]; to_map_ejson(Val) -> Val. --endif. % Random any term generation diff --git a/test/jiffy_15_return_trailer_tests.erl b/test/jiffy_15_return_trailer_tests.erl index 80937fa1..c8860c85 100644 --- a/test/jiffy_15_return_trailer_tests.erl +++ b/test/jiffy_15_return_trailer_tests.erl @@ -18,13 +18,9 @@ trailer_test_() -> ?_assertEqual(Result, jiffy:decode(Data, Opts)) end, Cases)}. --ifndef(JIFFY_NO_MAPS). - trailer_bignum_test() -> Opts = [return_maps, return_trailer], Data = <<"{\"amount\":-50000000000000000000}{}">>, Obj = #{<<"amount">> => -50000000000000000000}, Expect = {has_trailer, Obj, <<"{}">>}, ?assertEqual(Expect, jiffy:decode(Data, Opts)). - --endif. diff --git a/test/jiffy_17_copy_strings_tests.erl b/test/jiffy_17_copy_strings_tests.erl index 359b9971..5401c86d 100644 --- a/test/jiffy_17_copy_strings_tests.erl +++ b/test/jiffy_17_copy_strings_tests.erl @@ -24,10 +24,10 @@ check_binaries(_Bin) -> copy_strings_test_() -> Opts = [copy_strings], Cases = [ - <<"\"foo\"">>, - <<"[\"bar\"]">>, - <<"{\"foo\":\"bar\"}">>, - <<"{\"foo\":[\"bar\"]}">> + <<"\"xoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\"">>, + <<"[\"yoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\"]">>, + <<"{\"zoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\":\"woooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\"}">>, + <<"{\"koooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\":[\"loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\"]}">> ], {"Test copy_strings", lists:map(fun(Json) -> EJson = jiffy:decode(Json, Opts),