%% -*- erlang -*-

%% In Erlang 27, the expression +0.0 =:= -0.0 will evaluate to false
%% whereas in Erlang 26 and earlier, it evaluates to true.
%% In Erlang 26.1, as a prep for Erlang 27, using 0.0 in match expreessions or
%% in comparisons with =:= or =/= will result in a warning that hints about
%% rewriting the value to either +0.0 or -0.0.
%% This preprocessor definition is for we want to run something, eg a unit
%% test, in Erlang versions that can tell +0.0 and -0.0 apart.
NoHavePlusMinusZeroFloat =
                 case +0.0 =:= -0.0 of
                     true  -> [{d,'NO_HAVE_PLUS_MINUS_ZERO_FLOAT'}];
                     false -> []
                 end.

%% maps:merge_with/3 appeared in Erlang 24.0
NoHaveMapsMergeWith3 =
                 try maps:merge_with(fun(K, V1, V2) -> V1 + V2 end,
                                     #{a => 1}, #{a => 2}) of
                     #{a := 3} -> []
                 catch error:undef -> [{d,'NO_HAVE_MAPS_MERGE_WITH_3'}]
                 end.

%% The json module appeared in Erlang 27.0
NoHaveJsonModule =
                 try json:encode(true) of
                     <<"true">> -> []
                 catch error:undef -> [{d,'NO_HAVE_JSON_MODULE'}]
                 end.

%% Native records appeared in Erlang 29.0
NoHaveNativeRecords =
                 begin
                     {ok, Ts, _} = erl_scan:string("#a:b{f=1}.", 1),
                     case erl_parse:parse_exprs(Ts) of
                         {ok,_}    -> [];
                         {error,_} -> [{d,'NO_HAVE_NATIVE_RECORDS'}]
                     end
                 end.

%% Run property-based tests if available.
PropertyTesterOpts =
                 case [M || M <- [proper],
                            code:ensure_loaded(M) =:= {module, M}] of
                     [] ->
                         [{d, 'NO_HAVE_PROPERTY_TESTER'}];
                     Ms ->
                         [{d, string:uppercase(atom_to_list(M))} || M <- Ms]
                 end.

ConfigOpts = NoHavePlusMinusZeroFloat ++ NoHaveJsonModule ++
                 NoHaveNativeRecords ++ PropertyTesterOpts.

[{require_otp_vsn, ".*"},

 {pre_hooks,
  [{compile,
    "escript build/mk_version_hrl include/gpb_version.hrl.in"
    "        include/gpb_version.hrl"}
  ]},

 %% Erlang compiler options
 {erl_opts, [debug_info] ++ ConfigOpts},

 {erl_first_files, ["src/gpb_codegen.erl"]},

 %% This line is useful if you have gpb_eqc.erl symlinked to
 %% the symlink in the test/ directory.
 {eunit_compile_opts, [{i,"../include"}]},

 {edoc_opts, [{preprocess,true}, {pretty_printer,erl_pp}]},

 {hex, [{doc, edoc}]},

 {post_hooks,
   [{compile,
     "escript build/compile_descriptor"}
   ]},

 %% XRef checks to perform
 {xref_checks, [undefined_function_calls]},

 %% Clean files
 {clean_files, [".eunit", "ebin/*.beam", "include/gpb_version.hrl",
                "descr_src/gpb_descriptor.erl", "descr_src/gpb_descriptor.hrl"]}
].
