added code for dealing with strings. Initial commit for version strings
Signed-off-by: Eric Merritt <ericbmerritt@gmail.com>
This commit is contained in:
parent
9e6f98ba81
commit
b4981ff4b5
1 changed files with 117 additions and 0 deletions
117
src/ec_string.erl
Normal file
117
src/ec_string.erl
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
%%%-------------------------------------------------------------------
|
||||||
|
%%% @copyright (C) 2011, Erlware LLC
|
||||||
|
%%% @doc
|
||||||
|
%%% Helper functions for working with strings.
|
||||||
|
%%% @end
|
||||||
|
%%%-------------------------------------------------------------------
|
||||||
|
-module(ec_string).
|
||||||
|
|
||||||
|
-export([
|
||||||
|
compare_versions/2
|
||||||
|
]).
|
||||||
|
%%%===================================================================
|
||||||
|
%%% API
|
||||||
|
%%%===================================================================
|
||||||
|
|
||||||
|
%% @doc Is arbitrary version string A bigger than version string B?
|
||||||
|
%% Valid version string elements are either separated by . or - or both.
|
||||||
|
%% Final version string elements may have a numeric followed directly by an
|
||||||
|
%% alpha numeric and will be compared separately as in 12alpha.
|
||||||
|
%%
|
||||||
|
%% <pre>
|
||||||
|
%% Example: compare_versions("3-2-5-alpha", "3.10.6") will return false
|
||||||
|
%% compare_versions("3-2-alpha", "3.2.1-alpha") will return false
|
||||||
|
%% compare_versions("3-2alpha", "3.2.1-alpha") will return false
|
||||||
|
%% compare_versions("3.2.2", "3.2.2") will return false
|
||||||
|
%% compare_versions("3.2.1", "3.2.1-rc2") will return true
|
||||||
|
%% compare_versions("3.2.2", "3.2.1") will return true
|
||||||
|
%% </pre>
|
||||||
|
-spec compare_versions(VsnA::string(), VsnB::string()) -> boolean().
|
||||||
|
compare_versions(VsnA, VsnB) ->
|
||||||
|
compare(string:tokens(VsnA, ".-"),string:tokens(VsnB, ".-")).
|
||||||
|
|
||||||
|
%%%===================================================================
|
||||||
|
%%% Internal Functions
|
||||||
|
%%%===================================================================
|
||||||
|
|
||||||
|
compare([Str|TA], [Str|TB]) ->
|
||||||
|
compare(TA, TB);
|
||||||
|
compare([StrA|TA], [StrB|TB]) ->
|
||||||
|
fine_compare(split_numeric_alpha(StrA), TA,
|
||||||
|
split_numeric_alpha(StrB), TB);
|
||||||
|
compare([], [Str]) ->
|
||||||
|
not compare_against_nothing(Str);
|
||||||
|
compare([Str], []) ->
|
||||||
|
compare_against_nothing(Str);
|
||||||
|
compare([], [_,_|_]) ->
|
||||||
|
false;
|
||||||
|
compare([_,_|_], []) ->
|
||||||
|
true;
|
||||||
|
compare([], []) ->
|
||||||
|
false.
|
||||||
|
|
||||||
|
compare_against_nothing(Str) ->
|
||||||
|
case split_numeric_alpha(Str) of
|
||||||
|
{_StrDig, ""} -> true;
|
||||||
|
{"", _StrAlpha} -> false;
|
||||||
|
{_StrDig, _StrAlpha} -> true
|
||||||
|
end.
|
||||||
|
|
||||||
|
fine_compare({_StrDigA, StrA}, TA, {_StrDigB, _StrB}, _TB) when StrA /= "", TA /= [] ->
|
||||||
|
throw(invalid_version_string);
|
||||||
|
fine_compare({_StrDigA, _StrA}, _TA, {_StrDigB, StrB}, TB) when StrB /= "", TB /= [] ->
|
||||||
|
throw(invalid_version_string);
|
||||||
|
fine_compare({"", _StrA}, _TA, {StrDigB, _StrB}, _TB) when StrDigB /= "" ->
|
||||||
|
false;
|
||||||
|
fine_compare({StrDigA, _StrA}, _TA, {"", _StrB}, _TB) when StrDigA /= "" ->
|
||||||
|
true;
|
||||||
|
fine_compare({StrDig, ""}, _TA, {StrDig, StrB}, _TB) when StrB /= "" ->
|
||||||
|
true;
|
||||||
|
fine_compare({StrDig, StrA}, _TA, {StrDig, ""}, _TB) when StrA /= "" ->
|
||||||
|
false;
|
||||||
|
fine_compare({StrDig, StrA}, _TA, {StrDig, StrB}, _TB) ->
|
||||||
|
StrA > StrB;
|
||||||
|
fine_compare({StrDigA, _StrA}, _TA, {StrDigB, _StrB}, _TB) ->
|
||||||
|
list_to_integer(StrDigA) > list_to_integer(StrDigB).
|
||||||
|
|
||||||
|
%% In the case of a version sub part with a numeric then an alpha,
|
||||||
|
%% split out the numeric and alpha "24alpha" becomes {"24", "alpha"}
|
||||||
|
split_numeric_alpha(RawVsn) ->
|
||||||
|
{Num, Str} = split_numeric_alpha(RawVsn, {"", ""}),
|
||||||
|
{lists:reverse(Num), Str}.
|
||||||
|
|
||||||
|
split_numeric_alpha([], Acc) ->
|
||||||
|
Acc;
|
||||||
|
split_numeric_alpha([Dig|T], {PatchVsn, PatchStr})
|
||||||
|
when Dig >= $0 andalso Dig =< $9 ->
|
||||||
|
split_numeric_alpha(T, {[Dig|PatchVsn], PatchStr});
|
||||||
|
split_numeric_alpha(PatchStr, {PatchVsn, ""}) ->
|
||||||
|
{PatchVsn, PatchStr}.
|
||||||
|
|
||||||
|
|
||||||
|
%%%===================================================================
|
||||||
|
%%% Test Functions
|
||||||
|
%%%===================================================================
|
||||||
|
|
||||||
|
-ifndef(NOTEST).
|
||||||
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
|
split_numeric_alpha_test() ->
|
||||||
|
?assertMatch({"123", "alpha1"}, split_numeric_alpha("123alpha1")).
|
||||||
|
|
||||||
|
compare_versions_test() ->
|
||||||
|
?assertMatch(true, compare_versions("1.2.3", "1.2.3alpha")),
|
||||||
|
?assertMatch(true, compare_versions("1.2.3-beta", "1.2.3-alpha")),
|
||||||
|
?assertMatch(true, compare_versions("1-2-3", "1-2-3alpha")),
|
||||||
|
?assertMatch(true, compare_versions("1-2-3", "1-2-3-rc3")),
|
||||||
|
?assertMatch(true, compare_versions("1.2.3beta", "1.2.3alpha")),
|
||||||
|
?assertMatch(true, compare_versions("1.2.4", "1.2.3")),
|
||||||
|
?assertMatch(true, compare_versions("1.3.3", "1.2.3")),
|
||||||
|
?assertMatch(true, compare_versions("2.2.3", "1.2.3")),
|
||||||
|
?assertMatch(true, compare_versions("4.2.3", "3.10.3")),
|
||||||
|
?assertMatch(false, compare_versions("1.2.3", "2.2.3")),
|
||||||
|
?assertMatch(false, compare_versions("1.2.2", "1.3.t")),
|
||||||
|
?assertMatch(false, compare_versions("1.2t", "1.3.t")),
|
||||||
|
?assertThrow(invalid_version_string, compare_versions("1.b.2", "1.3.4")).
|
||||||
|
|
||||||
|
-endif.
|
Loading…
Add table
Add a link
Reference in a new issue