summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEvgeny Khramtsov <ekhramtsov@process-one.net>2019-04-30 09:36:38 +0300
committerEvgeny Khramtsov <ekhramtsov@process-one.net>2019-04-30 09:36:38 +0300
commit4af99f7b03ce44193192f75c492b9e28e99e2600 (patch)
tree993fb3d790fb069179f154ecd429ad1d7d1eecfe /src
parentProvide a suggestion when unknown module is detected (diff)
Rename ejabberd_config:similar_option/2 -> misc:best_match/2
Diffstat (limited to 'src')
-rw-r--r--src/ejabberd_config.erl32
-rw-r--r--src/gen_mod.erl4
-rw-r--r--src/misc.erl32
3 files changed, 35 insertions, 33 deletions
diff --git a/src/ejabberd_config.erl b/src/ejabberd_config.erl
index 40d157a8..f4abf8d5 100644
--- a/src/ejabberd_config.erl
+++ b/src/ejabberd_config.erl
@@ -39,7 +39,7 @@
default_queue_type/1, queue_dir/0, fsm_limit_opts/1,
use_cache/1, cache_size/1, cache_missed/1, cache_life_time/1,
codec_options/1, get_plain_terms_file/2, negotiation_timeout/0,
- similar_option/2, get_modules/0]).
+ get_modules/0]).
-export([start/2]).
@@ -1102,7 +1102,7 @@ validate_opts(#state{opts = Opts} = State, ModOpts) ->
_ ->
KnownOpts = dict:fetch_keys(ModOpts),
?ERROR_MSG("Unknown option '~s', did you mean '~s'?",
- [Opt, similar_option(Opt, KnownOpts)]),
+ [Opt, misc:best_match(Opt, KnownOpts)]),
erlang:error(unknown_option)
end
end, Opts),
@@ -1126,34 +1126,6 @@ is_file_readable(Path) ->
false
end.
--spec similar_option(atom(), [atom()]) -> atom().
-similar_option(Pattern, [_|_] = Opts) ->
- String = atom_to_list(Pattern),
- {Ds, _} = lists:mapfoldl(
- fun(Opt, Cache) ->
- {Distance, Cache1} = ld(String, atom_to_list(Opt), Cache),
- {{Distance, Opt}, Cache1}
- end, #{}, Opts),
- element(2, lists:min(Ds)).
-
-%% Levenshtein distance
--spec ld(string(), string(), map()) -> {non_neg_integer(), map()}.
-ld([] = S, T, Cache) ->
- {length(T), maps:put({S, T}, length(T), Cache)};
-ld(S, [] = T, Cache) ->
- {length(S), maps:put({S, T}, length(S), Cache)};
-ld([X|S], [X|T], Cache) ->
- ld(S, T, Cache);
-ld([_|ST] = S, [_|TT] = T, Cache) ->
- try {maps:get({S, T}, Cache), Cache}
- catch _:{badkey, _} ->
- {L1, C1} = ld(S, TT, Cache),
- {L2, C2} = ld(ST, T, C1),
- {L3, C3} = ld(ST, TT, C2),
- L = 1 + lists:min([L1, L2, L3]),
- {L, maps:put({S, T}, L, C3)}
- end.
-
get_version() ->
case application:get_env(ejabberd, custom_vsn) of
{ok, Vsn0} when is_list(Vsn0) ->
diff --git a/src/gen_mod.erl b/src/gen_mod.erl
index eb433de5..b972285f 100644
--- a/src/gen_mod.erl
+++ b/src/gen_mod.erl
@@ -585,7 +585,7 @@ validate_opts(Host, Module, Opts0) ->
" did you mean '~s'?"
" Available options are: ~s",
[Opt, Module,
- ejabberd_config:similar_option(Opt, KnownOpts),
+ misc:best_match(Opt, KnownOpts),
misc:join_atoms(KnownOpts, <<", ">>)]),
module_error(ErrTxt)
end.
@@ -746,7 +746,7 @@ format_module_error(Module, Fun, Arity, Opts, Class, Reason, St) ->
"exists inside either ~s or ~s "
"directory",
[Fun, Module,
- ejabberd_config:similar_option(
+ misc:best_match(
Module, ejabberd_config:get_modules()),
Module,
filename:dirname(code:which(?MODULE)),
diff --git a/src/misc.erl b/src/misc.erl
index 73d05ff2..4f683a43 100644
--- a/src/misc.erl
+++ b/src/misc.erl
@@ -39,7 +39,7 @@
css_dir/0, img_dir/0, js_dir/0, msgs_dir/0, sql_dir/0, lua_dir/0,
read_css/1, read_img/1, read_js/1, read_lua/1, try_url/1,
intersection/2, format_val/1, cancel_timer/1, unique_timestamp/0,
- is_mucsub_message/1]).
+ is_mucsub_message/1, best_match/2]).
%% Deprecated functions
-export([decode_base64/1, encode_base64/1]).
@@ -425,6 +425,18 @@ cancel_timer(TRef) when is_reference(TRef) ->
cancel_timer(_) ->
ok.
+-spec best_match(atom(), [atom()]) -> atom().
+best_match(Pattern, []) ->
+ Pattern;
+best_match(Pattern, Opts) ->
+ String = atom_to_list(Pattern),
+ {Ds, _} = lists:mapfoldl(
+ fun(Opt, Cache) ->
+ {Distance, Cache1} = ld(String, atom_to_list(Opt), Cache),
+ {{Distance, Opt}, Cache1}
+ end, #{}, Opts),
+ element(2, lists:min(Ds)).
+
%%%===================================================================
%%% Internal functions
%%%===================================================================
@@ -485,3 +497,21 @@ get_dir(Type) ->
unique_timestamp() ->
{MS, S, _} = erlang:timestamp(),
{MS, S, erlang:unique_integer([positive, monotonic]) rem 1000000}.
+
+%% Levenshtein distance
+-spec ld(string(), string(), map()) -> {non_neg_integer(), map()}.
+ld([] = S, T, Cache) ->
+ {length(T), maps:put({S, T}, length(T), Cache)};
+ld(S, [] = T, Cache) ->
+ {length(S), maps:put({S, T}, length(S), Cache)};
+ld([X|S], [X|T], Cache) ->
+ ld(S, T, Cache);
+ld([_|ST] = S, [_|TT] = T, Cache) ->
+ try {maps:get({S, T}, Cache), Cache}
+ catch _:{badkey, _} ->
+ {L1, C1} = ld(S, TT, Cache),
+ {L2, C2} = ld(ST, T, C1),
+ {L3, C3} = ld(ST, TT, C2),
+ L = 1 + lists:min([L1, L2, L3]),
+ {L, maps:put({S, T}, L, C3)}
+ end.