diff options
Diffstat (limited to 'src/gen_mod.erl')
-rw-r--r-- | src/gen_mod.erl | 109 |
1 files changed, 55 insertions, 54 deletions
diff --git a/src/gen_mod.erl b/src/gen_mod.erl index 1e069be7..ed04767c 100644 --- a/src/gen_mod.erl +++ b/src/gen_mod.erl @@ -546,89 +546,94 @@ validate_opts(Host, Module, Opts0) -> catch _:undef -> [] end end, [Module|SubMods]), - Required = lists:filter(fun is_atom/1, DefaultOpts), try Opts = merge_opts(Opts0, DefaultOpts, Module), {ok, case get_validators(Host, {Module, SubMods}) of undef -> Opts; Validators -> - Opts1 = validate_opts(Host, Module, Opts, Required, Validators), + Opts1 = validate_opts(Host, Module, Opts, Validators), remove_duplicated_opts(Opts1) end} catch _:{missing_required_option, Opt} -> ErrTxt = io_lib:format("Module '~s' is missing required option '~s'", [Module, Opt]), - ?ERROR_MSG(ErrTxt, []), - {error, ErrTxt} + module_error(ErrTxt); + _:{invalid_option, Opt, Val} -> + ErrTxt = io_lib:format("Invalid value '~p' for option '~s' of " + "module '~s'", [Val, Opt, Module]), + module_error(ErrTxt); + _:{invalid_option, Opt, Val, Reason} -> + ErrTxt = io_lib:format("Invalid value '~p' for option '~s' of " + "module '~s': ~s", [Val, Opt, Module, Reason]), + module_error(ErrTxt); + _:{unknown_option, Opt, []} -> + ErrTxt = io_lib:format("Unknown option '~s' of module '~s': " + "the module doesn't have any options", + [Opt, Module]), + module_error(ErrTxt); + _:{unknown_option, Opt, KnownOpts} -> + ErrTxt = io_lib:format("Unknown option '~s' of module '~s'," + " available options are: ~s", + [Opt, Module, + misc:join_atoms(KnownOpts, <<", ">>)]), + module_error(ErrTxt) end. -validate_opts(Host, Module, Opts, Required, Validators) when is_list(Opts) -> +-spec module_error(iolist()) -> {error, iolist()}. +module_error(ErrTxt) -> + ?ERROR_MSG(ErrTxt, []), + {error, ErrTxt}. + +-spec err_invalid_option(atom(), any()) -> no_return(). +err_invalid_option(Opt, Val) -> + erlang:error({invalid_option, Opt, Val}). + +-spec err_invalid_option(atom(), any(), iolist()) -> no_return(). +err_invalid_option(Opt, Val, Reason) -> + erlang:error({invalid_option, Opt, Val, Reason}). + +-spec err_unknown_option(atom(), [atom()]) -> no_return(). +err_unknown_option(Opt, KnownOpts) -> + erlang:error({unknown_option, Opt, KnownOpts}). + +-spec err_missing_required_option(atom()) -> no_return(). +err_missing_required_option(Opt) -> + erlang:error({missing_required_option, Opt}). + +validate_opts(Host, Module, Opts, Validators) when is_list(Opts) -> lists:flatmap( fun({Opt, Val}) when is_atom(Opt) -> case lists:keyfind(Opt, 1, Validators) of {_, L} -> case lists:partition(fun is_function/1, L) of {[VFun|_], []} -> - validate_opt(Module, Opt, Val, Required, VFun); + validate_opt(Opt, Val, VFun); {[VFun|_], SubValidators} -> - try validate_opts(Host, Module, Val, Required, SubValidators) of + try validate_opts(Host, Module, Val, SubValidators) of SubOpts -> - validate_opt(Module, Opt, SubOpts, Required, VFun) + validate_opt(Opt, SubOpts, VFun) catch _:bad_option -> - ?ERROR_MSG("Ignoring invalid value '~p' for " - "option '~s' of module '~s'", - [Val, Opt, Module]), - fail_if_option_is_required(Opt, Required), - [] + err_invalid_option(Opt, Val) end end; false -> - case Validators of - [] -> - ?ERROR_MSG("Ignoring unknown option '~s' of '~s':" - " the module doesn't have any options", - [Opt, Module]); - _ -> - ?ERROR_MSG("Ignoring unknown option '~s' of '~s'," - " available options are: ~s", - [Opt, Module, - misc:join_atoms( - [K || {K, _} <- Validators], - <<", ">>)]) - end, - [] + err_unknown_option(Opt, [K || {K, _} <- Validators]) end; (_) -> erlang:error(bad_option) end, Opts); -validate_opts(_, _, _, _, _) -> +validate_opts(_, _, _, _) -> erlang:error(bad_option). --spec validate_opt(module(), atom(), any(), [atom()], - [{atom(), check_fun(), any()}]) -> [{atom(), any()}]. -validate_opt(Module, Opt, Val, Required, VFun) -> +-spec validate_opt(atom(), any(), check_fun()) -> [{atom(), any()}]. +validate_opt(Opt, Val, VFun) -> try VFun(Val) of NewVal -> [{Opt, NewVal}] catch {invalid_syntax, Error} -> - ?ERROR_MSG("Ignoring invalid value '~p' for " - "option '~s' of module '~s': ~s", - [Val, Opt, Module, Error]), - fail_if_option_is_required(Opt, Required), - []; + err_invalid_option(Opt, Val, Error); _:_ -> - ?ERROR_MSG("Ignoring invalid value '~p' for " - "option '~s' of module '~s'", - [Val, Opt, Module]), - fail_if_option_is_required(Opt, Required), - [] - end. - --spec fail_if_option_is_required(atom(), [atom()]) -> ok | no_return(). -fail_if_option_is_required(Opt, Required) -> - case lists:member(Opt, Required) of - true -> erlang:error({missing_required_option, Opt}); - false -> ok + err_invalid_option(Opt, Val) end. -spec list_known_opts(binary(), module()) -> [atom() | {atom(), atom()}]. @@ -658,11 +663,7 @@ merge_opts(Opts, DefaultOpts, Module) -> true -> [{Opt, merge_opts(Val, Default, Module)}|Acc]; false -> - ?ERROR_MSG( - "Ignoring invalid value '~p' for " - "option '~s' of module '~s'", - [Val, Opt, Module]), - [{Opt, Default}|Acc] + err_invalid_option(Opt, Val) end; Val -> [{Opt, Default}|Acc]; @@ -677,7 +678,7 @@ merge_opts(Opts, DefaultOpts, Module) -> {_, Val} -> [{Opt, Val}|Acc]; false -> - erlang:error({missing_required_option, Opt}) + err_missing_required_option(Opt) end end, [], DefaultOpts), lists:foldl( |