%% -*- mode: erlang;erlang-indent-level: 2;indent-tabs-mode: nil -*-
%% vim: set ft=erlang ts=2 sw=2:

%% this code is not particularly nice.
%% the idea is to test for the presence of functions, in order to set
%% preprocessor flags, so that we can use the preprocessor to hide new
%% functions from old compilers.
%% "erl_opts" gets passed to the compiler.
%% "CONFIG" is a magic rebar thing.
%% The foldl takes a [{function(Predicate/0),atom(Macro)}].
%% If the Predicate is false, the Macro is passed to the compiler.
%% Predicate should test for presence of new functions, and the Macro
%% should be used to enable old functions. That way new functions are
%% enabled by default.

KeyAppend =
fun(Tag,[],E,_)          -> [{Tag,[E]}];
   (Tag,[{Tag,O}|T],E,_) -> [{Tag,[E|O]}|T];
   (Tag,[H|T],E,G)       -> [H|G(Tag,T,E,G)]
end,

Check =
fun(CFG,Predicate,Macro) ->
    case Predicate() of
      false -> KeyAppend(erl_opts,CFG,{d,Macro},KeyAppend);
      true  -> CFG
    end
end,

lists:foldl(
  fun({Predicate,Macro},Cfg) -> Check(Cfg,Predicate,Macro) end,
  CONFIG,
  [{fun() -> code:ensure_loaded(crypto),
             erlang:function_exported(crypto,block_encrypt,4)
    end,
    'USE_PRE_R16_CRYPTO'},
   {fun() -> erlang:is_builtin(erlang,timestamp,0)
    end,
    'USE_NOW'}]).
