Merge remote-tracking branch 'canonical/next'

This commit is contained in:
Eric Merritt 2013-01-21 10:55:52 -08:00
commit 4811393957
9 changed files with 221 additions and 36 deletions

View file

@ -1,9 +1,11 @@
language: erlang =nlanguage: erlang
otp_release: otp_release:
- R15B02 - R15B02
- R15B01 - R15B01
- R15B - R15B
- R14B04
- R14B03
- R14B02
before_script: "make get-deps" before_script: "make get-deps"
script: "make" script: "make"
branches: branches:

View file

@ -39,7 +39,7 @@ $(ERLWARE_COMMONS_PLT):
--apps erts kernel stdlib eunit -r deps --apps erts kernel stdlib eunit -r deps
dialyzer: $(ERLWARE_COMMONS_PLT) dialyzer: $(ERLWARE_COMMONS_PLT)
dialyzer --fullpath --plt $(ERLWARE_COMMONS_PLT) -Wrace_conditions --src src dialyzer --fullpath --plt $(ERLWARE_COMMONS_PLT) -Wrace_conditions -r ./ebin
typer: typer:
typer --plt $(ERLWARE_COMMONS_PLT) -r ./src typer --plt $(ERLWARE_COMMONS_PLT) -r ./src
@ -64,4 +64,4 @@ distclean: clean
rm -rf $(ERLWARE_COMMONS_PLT) rm -rf $(ERLWARE_COMMONS_PLT)
rm -rvf $(CURDIR)/deps/* rm -rvf $(CURDIR)/deps/*
rebuild: distclean all rebuild: distclean get-deps all

View file

@ -3,7 +3,7 @@
%% Dependencies ================================================================ %% Dependencies ================================================================
{deps, [{neotoma, "", {deps, [{neotoma, "",
{git, "https://github.com/seancribbs/neotoma.git", {branch, master}}}, {git, "https://github.com/seancribbs/neotoma.git", {branch, master}}},
{proper, "", {git, "https://github.com/manopapad/proper.git", {branch, master}}}, {proper, "", {git, "https://github.com/bkearns/proper.git", {branch, master}}},
{rebar_vsn_plugin, ".*", {git, "https://github.com/erlware/rebar_vsn_plugin.git", {rebar_vsn_plugin, ".*", {git, "https://github.com/erlware/rebar_vsn_plugin.git",
{branch, "master"}}}]}. {branch, "master"}}}]}.

15
rebar.config.script Normal file
View file

@ -0,0 +1,15 @@
{match, [ErtsNumber]} = re:run("R15B02", "R(\\d+).+", [{capture, [1], list}]),
ErtsVsn = erlang:list_to_integer(ErtsNumber),
Opts1 = case lists:keysearch(erl_opts, 1, CONFIG) of
{value, {erl_opts, Opts0}} ->
Opts0;
false ->
[]
end,
Opts2 = if
ErtsVsn >= 15 ->
[{d, have_callback_support} | Opts1];
true ->
Opts1
end,
lists:keystore(erl_opts, 1, CONFIG, {erl_opts, Opts2}).

View file

@ -13,9 +13,11 @@
erl_source_to_core_ast/1, erl_source_to_core_ast/1,
erl_source_to_erl_ast/1, erl_source_to_erl_ast/1,
erl_source_to_asm/1, erl_source_to_asm/1,
erl_source_to_erl_syntax/1,
erl_string_to_core_ast/1, erl_string_to_core_ast/1,
erl_string_to_erl_ast/1, erl_string_to_erl_ast/1,
erl_string_to_asm/1]). erl_string_to_asm/1,
erl_string_to_erl_syntax/1]).
%%%=================================================================== %%%===================================================================
%%% API %%% API
@ -33,13 +35,13 @@
beam_to_erl_source(BeamFName, ErlFName) -> beam_to_erl_source(BeamFName, ErlFName) ->
case beam_lib:chunks(BeamFName, [abstract_code]) of case beam_lib:chunks(BeamFName, [abstract_code]) of
{ok, {_, [{abstract_code, {raw_abstract_v1,Forms}}]}} -> {ok, {_, [{abstract_code, {raw_abstract_v1,Forms}}]}} ->
Src = Src =
erl_prettypr:format(erl_syntax:form_list(tl(Forms))), erl_prettypr:format(erl_syntax:form_list(tl(Forms))),
{ok, Fd} = file:open(ErlFName, [write]), {ok, Fd} = file:open(ErlFName, [write]),
io:fwrite(Fd, "~s~n", [Src]), io:fwrite(Fd, "~s~n", [Src]),
file:close(Fd); file:close(Fd);
Error -> Error ->
Error Error
end. end.
%% @doc compile an erlang source file into a Core Erlang AST %% @doc compile an erlang source file into a Core Erlang AST
@ -67,6 +69,15 @@ erl_source_to_asm(Path) ->
{ok, Contents} = file:read_file(Path), {ok, Contents} = file:read_file(Path),
erl_string_to_asm(binary_to_list(Contents)). erl_string_to_asm(binary_to_list(Contents)).
%% @doc compile an erlang source file to a string that displays the
%% 'erl_syntax1 calls needed to reproduce those terms.
%%
%% @param Path - The path to the erlang source file
-spec erl_source_to_erl_syntax(file:filename()) -> string().
erl_source_to_erl_syntax(Path) ->
{ok, Contents} = file:read_file(Path),
erl_string_to_erl_syntax(Contents).
%% @doc compile a string representing an erlang expression into an %% @doc compile a string representing an erlang expression into an
%% Erlang AST %% Erlang AST
%% %%
@ -105,3 +116,16 @@ erl_string_to_core_ast(StringExpr) ->
-spec erl_string_to_asm(string()) -> ErlangAsm::term(). -spec erl_string_to_asm(string()) -> ErlangAsm::term().
erl_string_to_asm(StringExpr) -> erl_string_to_asm(StringExpr) ->
compile:forms(erl_string_to_erl_ast(StringExpr), ['S']). compile:forms(erl_string_to_erl_ast(StringExpr), ['S']).
%% @doc compile an erlang source file to a string that displays the
%% 'erl_syntax1 calls needed to reproduce those terms.
%%
%% @param StringExpr - The string representing the erlang code.
-spec erl_string_to_erl_syntax(string() | binary()) -> string().
erl_string_to_erl_syntax(BinaryExpr)
when erlang:is_binary(BinaryExpr) ->
erlang:binary_to_list(BinaryExpr);
erl_string_to_erl_syntax(StringExpr) ->
{ok, Tokens, _} = erl_scan:string(StringExpr),
{ok, ErlAST} = erl_parse:parse_form(Tokens),
io:format(erl_prettypr:format(erl_syntax:meta(ErlAST))).

View file

@ -42,9 +42,11 @@
-type hour() :: 0..23. -type hour() :: 0..23.
-type minute() :: 0..59. -type minute() :: 0..59.
-type second() :: 0..59. -type second() :: 0..59.
-type microsecond() :: 0..1000000.
-type daynum() :: 1..7. -type daynum() :: 1..7.
-type date() :: {year(),month(),day()}. -type date() :: {year(),month(),day()}.
-type time() :: {hour(),minute(),second()}. -type time() :: {hour(),minute(),second()} |{hour(),minute(),second(), microsecond()}.
-type datetime() :: {date(),time()}. -type datetime() :: {date(),time()}.
-type now() :: {integer(),integer(),integer()}. -type now() :: {integer(),integer(),integer()}.
@ -59,8 +61,9 @@ format(Format) ->
-spec format(string(),datetime() | now()) -> string(). -spec format(string(),datetime() | now()) -> string().
%% @doc format Date as Format %% @doc format Date as Format
format(Format, {_,_,_}=Now) -> format(Format, {_,_,Ms}=Now) ->
format(Format, calendar:now_to_datetime(Now), []); {Date,{H,M,S}} = calendar:now_to_datetime(Now),
format(Format, {Date, {H,M,S,Ms}}, []);
format(Format, Date) -> format(Format, Date) ->
format(Format, Date, []). format(Format, Date, []).
@ -70,6 +73,7 @@ parse(Date) ->
do_parse(Date, calendar:universal_time(),[]). do_parse(Date, calendar:universal_time(),[]).
-spec parse(string(),datetime() | now()) -> datetime(). -spec parse(string(),datetime() | now()) -> datetime().
%% @doc parses the datetime from a string %% @doc parses the datetime from a string
parse(Date, {_,_,_}=Now) -> parse(Date, {_,_,_}=Now) ->
do_parse(Date, calendar:now_to_datetime(Now), []); do_parse(Date, calendar:now_to_datetime(Now), []);
@ -88,22 +92,61 @@ do_parse(Date, Now, Opts) ->
true -> {D1, T1}; true -> {D1, T1};
false -> erlang:throw({?MODULE, {bad_date, Date}}) false -> erlang:throw({?MODULE, {bad_date, Date}})
end; end;
_ -> erlang:throw({?MODULE, {bad_date, Date}}) {D1, _T1, {Ms}} = {{Y, M, D}, {H, M1, S}, {Ms}}
when is_number(Y), is_number(M),
is_number(D), is_number(H),
is_number(M1), is_number(S),
is_number(Ms) ->
case calendar:valid_date(D1) of
true -> {D1, {H,M1,S,Ms}};
false -> erlang:throw({?MODULE, {bad_date, Date}})
end;
Unknown -> erlang:throw({?MODULE, {bad_date, Date, Unknown }})
end. end.
-spec nparse(string()) -> now(). -spec nparse(string()) -> now().
%% @doc parses the datetime from a string into 'now' format %% @doc parses the datetime from a string into 'now' format
nparse(Date) -> nparse(Date) ->
DateTime = parse(Date), case parse(Date) of
GSeconds = calendar:datetime_to_gregorian_seconds(DateTime), {DateS, {H, M, S, Ms} } ->
ESeconds = GSeconds - ?GREGORIAN_SECONDS_1970, GSeconds = calendar:datetime_to_gregorian_seconds({DateS, {H, M, S} }),
{ESeconds div 1000000, ESeconds rem 1000000, 0}. ESeconds = GSeconds - ?GREGORIAN_SECONDS_1970,
{ESeconds div 1000000, ESeconds rem 1000000, Ms};
DateTime ->
GSeconds = calendar:datetime_to_gregorian_seconds(DateTime),
ESeconds = GSeconds - ?GREGORIAN_SECONDS_1970,
{ESeconds div 1000000, ESeconds rem 1000000, 0}
end.
%% %%
%% LOCAL FUNCTIONS %% LOCAL FUNCTIONS
%% %%
%% Date/Times 22 Aug 2008 6:35.0001 PM
parse([Year,X,Month,X,Day,Hour,$:,Min,$:,Sec,$., Ms | PAM], _Now, _Opts)
when ?is_meridian(PAM) andalso
(?is_us_sep(X) orelse ?is_world_sep(X))
andalso Year > 31 ->
{{Year, Month, Day}, {hour(Hour, PAM), Min, Sec}, {Ms}};
parse([Month,X,Day,X,Year,Hour,$:,Min,$:,Sec,$., Ms | PAM], _Now, _Opts)
when ?is_meridian(PAM) andalso ?is_us_sep(X) ->
{{Year, Month, Day}, {hour(Hour, PAM), Min, Sec}, {Ms}};
parse([Day,X,Month,X,Year,Hour,$:,Min,$:,Sec,$., Ms | PAM], _Now, _Opts)
when ?is_meridian(PAM) andalso ?is_world_sep(X) ->
{{Year, Month, Day}, {hour(Hour, PAM), Min, Sec}, {Ms}};
parse([Year,X,Month,X,Day,Hour,$:,Min,$:,Sec,$., Ms], _Now, _Opts)
when (?is_us_sep(X) orelse ?is_world_sep(X))
andalso Year > 31 ->
{{Year, Month, Day}, {hour(Hour,[]), Min, Sec}, {Ms}};
parse([Month,X,Day,X,Year,Hour,$:,Min,$:,Sec,$., Ms], _Now, _Opts)
when ?is_us_sep(X) ->
{{Year, Month, Day}, {hour(Hour, []), Min, Sec}, {Ms}};
parse([Day,X,Month,X,Year,Hour,$:,Min,$:,Sec,$., Ms ], _Now, _Opts)
when ?is_world_sep(X) ->
{{Year, Month, Day}, {hour(Hour, []), Min, Sec}, {Ms}};
%% Times - 21:45, 13:45:54, 13:15PM etc %% Times - 21:45, 13:45:54, 13:15PM etc
parse([Hour,$:,Min,$:,Sec | PAM], {Date, _Time}, _O) when ?is_meridian(PAM) -> parse([Hour,$:,Min,$:,Sec | PAM], {Date, _Time}, _O) when ?is_meridian(PAM) ->
{Date, {hour(Hour, PAM), Min, Sec}}; {Date, {hour(Hour, PAM), Min, Sec}};
@ -138,7 +181,8 @@ parse([Month,X,Day,X,Year,Hour | PAM], _Date, _Opts)
when ?is_meridian(PAM) andalso ?is_us_sep(X) -> when ?is_meridian(PAM) andalso ?is_us_sep(X) ->
{{Year, Month, Day}, {hour(Hour, PAM), 0, 0}}; {{Year, Month, Day}, {hour(Hour, PAM), 0, 0}};
%% Time is "6:35 PM"
%% Time is "6:35 PM" ms return
parse([Year,X,Month,X,Day,Hour,$:,Min | PAM], _Date, _Opts) parse([Year,X,Month,X,Day,Hour,$:,Min | PAM], _Date, _Opts)
when ?is_meridian(PAM) andalso when ?is_meridian(PAM) andalso
(?is_us_sep(X) orelse ?is_world_sep(X)) (?is_us_sep(X) orelse ?is_world_sep(X))
@ -164,7 +208,6 @@ parse([Day,X,Month,X,Year,Hour,$:,Min,$:,Sec | PAM], _Now, _Opts)
when ?is_meridian(PAM) andalso ?is_world_sep(X) -> when ?is_meridian(PAM) andalso ?is_world_sep(X) ->
{{Year, Month, Day}, {hour(Hour, PAM), Min, Sec}}; {{Year, Month, Day}, {hour(Hour, PAM), Min, Sec}};
parse([Day,Month,Year,Hour | PAM], _Now, _Opts) parse([Day,Month,Year,Hour | PAM], _Now, _Opts)
when ?is_meridian(PAM) -> when ?is_meridian(PAM) ->
{{Year, Month, Day}, {hour(Hour, PAM), 0, 0}}; {{Year, Month, Day}, {hour(Hour, PAM), 0, 0}};
@ -181,9 +224,18 @@ parse(_Tokens, _Now, _Opts) ->
tokenise([], Acc) -> tokenise([], Acc) ->
lists:reverse(Acc); lists:reverse(Acc);
tokenise([N1, N2, N3, N4, N5, N6 | Rest], Acc)
when ?is_num(N1), ?is_num(N2), ?is_num(N3), ?is_num(N4), ?is_num(N5), ?is_num(N6) ->
tokenise(Rest, [ ltoi([N1, N2, N3, N4, N5, N6]) | Acc]);
tokenise([N1, N2, N3, N4, N5 | Rest], Acc)
when ?is_num(N1), ?is_num(N2), ?is_num(N3), ?is_num(N4), ?is_num(N5) ->
tokenise(Rest, [ ltoi([N1, N2, N3, N4, N5]) | Acc]);
tokenise([N1, N2, N3, N4 | Rest], Acc) tokenise([N1, N2, N3, N4 | Rest], Acc)
when ?is_num(N1), ?is_num(N2), ?is_num(N3), ?is_num(N4) -> when ?is_num(N1), ?is_num(N2), ?is_num(N3), ?is_num(N4) ->
tokenise(Rest, [ ltoi([N1, N2, N3, N4]) | Acc]); tokenise(Rest, [ ltoi([N1, N2, N3, N4]) | Acc]);
tokenise([N1, N2, N3 | Rest], Acc)
when ?is_num(N1), ?is_num(N2), ?is_num(N3) ->
tokenise(Rest, [ ltoi([N1, N2, N3]) | Acc]);
tokenise([N1, N2 | Rest], Acc) tokenise([N1, N2 | Rest], Acc)
when ?is_num(N1), ?is_num(N2) -> when ?is_num(N1), ?is_num(N2) ->
tokenise(Rest, [ ltoi([N1, N2]) | Acc]); tokenise(Rest, [ ltoi([N1, N2]) | Acc]);
@ -264,6 +316,8 @@ tokenise("TH"++Rest, Acc) -> tokenise(Rest, Acc);
tokenise("ND"++Rest, Acc) -> tokenise(Rest, Acc); tokenise("ND"++Rest, Acc) -> tokenise(Rest, Acc);
tokenise("ST"++Rest, Acc) -> tokenise(Rest, Acc); tokenise("ST"++Rest, Acc) -> tokenise(Rest, Acc);
tokenise("OF"++Rest, Acc) -> tokenise(Rest, Acc); tokenise("OF"++Rest, Acc) -> tokenise(Rest, Acc);
tokenise("T"++Rest, Acc) -> tokenise(Rest, Acc); % 2012-12-12T12:12:12 ISO formatting.
tokenise([$. | Rest], Acc) -> tokenise(Rest, [$. | Acc]); % 2012-12-12T12:12:12.xxxx ISO formatting.
tokenise([Else | Rest], Acc) -> tokenise([Else | Rest], Acc) ->
tokenise(Rest, [{bad_token, Else} | Acc]). tokenise(Rest, [{bad_token, Else} | Acc]).
@ -329,13 +383,13 @@ format([$z|T], {Date,_}=Dt, Acc) ->
format(T, Dt, [itol(days_in_year(Date))|Acc]); format(T, Dt, [itol(days_in_year(Date))|Acc]);
%% Time Formats %% Time Formats
format([$a|T], {_,{H,_,_}}=Dt, Acc) when H > 12 -> format([$a|T], Dt={_,{H,_,_}}, Acc) when H > 12 ->
format(T, Dt, ["pm"|Acc]); format(T, Dt, ["pm"|Acc]);
format([$a|T], Dt, Acc) -> format([$a|T], Dt={_,{_,_,_}}, Acc) ->
format(T, Dt, ["am"|Acc]); format(T, Dt, ["am"|Acc]);
format([$A|T], {_,{H,_,_}}=Dt, Acc) when H > 12 -> format([$A|T], {_,{H,_,_}}=Dt, Acc) when H > 12 ->
format(T, Dt, ["PM"|Acc]); format(T, Dt, ["PM"|Acc]);
format([$A|T], Dt, Acc) -> format([$A|T], Dt={_,{_,_,_}}, Acc) ->
format(T, Dt, ["AM"|Acc]); format(T, Dt, ["AM"|Acc]);
format([$g|T], {_,{H,_,_}}=Dt, Acc) when H == 12; H == 0 -> format([$g|T], {_,{H,_,_}}=Dt, Acc) when H == 12; H == 0 ->
format(T, Dt, ["12"|Acc]); format(T, Dt, ["12"|Acc]);
@ -355,6 +409,38 @@ format([$i|T], {_,{_,M,_}}=Dt, Acc) ->
format(T, Dt, [pad2(M)|Acc]); format(T, Dt, [pad2(M)|Acc]);
format([$s|T], {_,{_,_,S}}=Dt, Acc) -> format([$s|T], {_,{_,_,S}}=Dt, Acc) ->
format(T, Dt, [pad2(S)|Acc]); format(T, Dt, [pad2(S)|Acc]);
format([$f|T], {_,{_,_,_}}=Dt, Acc) ->
format(T, Dt, [itol(0)|Acc]);
%% Time Formats ms
format([$a|T], Dt={_,{H,_,_,_}}, Acc) when H > 12 ->
format(T, Dt, ["pm"|Acc]);
format([$a|T], Dt={_,{_,_,_,_}}, Acc) ->
format(T, Dt, ["am"|Acc]);
format([$A|T], {_,{H,_,_,_}}=Dt, Acc) when H > 12 ->
format(T, Dt, ["PM"|Acc]);
format([$A|T], Dt={_,{_,_,_,_}}, Acc) ->
format(T, Dt, ["AM"|Acc]);
format([$g|T], {_,{H,_,_,_}}=Dt, Acc) when H == 12; H == 0 ->
format(T, Dt, ["12"|Acc]);
format([$g|T], {_,{H,_,_,_}}=Dt, Acc) when H > 12 ->
format(T, Dt, [itol(H-12)|Acc]);
format([$g|T], {_,{H,_,_,_}}=Dt, Acc) ->
format(T, Dt, [itol(H)|Acc]);
format([$G|T], {_,{H,_,_,_}}=Dt, Acc) ->
format(T, Dt, [itol(H)|Acc]);
format([$h|T], {_,{H,_,_,_}}=Dt, Acc) when H > 12 ->
format(T, Dt, [pad2(H-12)|Acc]);
format([$h|T], {_,{H,_,_,_}}=Dt, Acc) ->
format(T, Dt, [pad2(H)|Acc]);
format([$H|T], {_,{H,_,_,_}}=Dt, Acc) ->
format(T, Dt, [pad2(H)|Acc]);
format([$i|T], {_,{_,M,_,_}}=Dt, Acc) ->
format(T, Dt, [pad2(M)|Acc]);
format([$s|T], {_,{_,_,S,_}}=Dt, Acc) ->
format(T, Dt, [pad2(S)|Acc]);
format([$f|T], {_,{_,_,_,Ms}}=Dt, Acc) ->
format(T, Dt, [itol(Ms)|Acc]);
%% Whole Dates %% Whole Dates
format([$c|T], {{Y,M,D},{H,Min,S}}=Dt, Acc) -> format([$c|T], {{Y,M,D},{H,Min,S}}=Dt, Acc) ->
@ -519,6 +605,7 @@ ltoi(X) ->
-include_lib("eunit/include/eunit.hrl"). -include_lib("eunit/include/eunit.hrl").
-define(DATE, {{2001,3,10},{17,16,17}}). -define(DATE, {{2001,3,10},{17,16,17}}).
-define(DATEMS, {{2001,3,10},{17,16,17,123456}}).
-define(ISO, "o \\WW"). -define(ISO, "o \\WW").
basic_format_test_() -> basic_format_test_() ->
@ -674,3 +761,20 @@ iso_test_() ->
?_assertEqual("2009 W53",format(?ISO,{{2009,12,31},{1,1,1}})), ?_assertEqual("2009 W53",format(?ISO,{{2009,12,31},{1,1,1}})),
?_assertEqual("2009 W53",format(?ISO,{{2010,1,3}, {1,1,1}})) ?_assertEqual("2009 W53",format(?ISO,{{2010,1,3}, {1,1,1}}))
]. ].
ms_test_() ->
Now=now(),
[
?_assertEqual({{2012,12,12}, {12,12,12,1234}}, parse("2012-12-12T12:12:12.1234")),
?_assertEqual(format("H:m:s.f \\m \\i\\s \\m\\o\\n\\t\\h",?DATEMS),
"17:03:17.123456 m is month"),
?_assertEqual(format("Y-m-d\\TH:i:s.f",?DATEMS),
"2001-03-10T17:16:17.123456"),
?_assertEqual(format("Y-m-d\\TH:i:s.f",nparse("2001-03-10T05:16:17.123456")),
"2001-03-10T05:16:17.123456"),
?_assertEqual(format("Y-m-d\\TH:i:s.f",nparse("2001-03-10T05:16:17.123456")),
"2001-03-10T05:16:17.123456"),
?_assertEqual(format("Y-m-d\\TH:i:s.f",nparse("2001-03-10T15:16:17.123456")),
"2001-03-10T15:16:17.123456"),
?_assertEqual(Now, nparse(format("Y-m-d\\TH:i:s.f", Now)))
].

View file

@ -41,6 +41,8 @@
-type key(T) :: T. -type key(T) :: T.
-type value(T) :: T. -type value(T) :: T.
-ifdef(have_callback_support).
-callback new() -> any(). -callback new() -> any().
-callback has_key(key(any()), any()) -> boolean(). -callback has_key(key(any()), any()) -> boolean().
-callback get(key(any()), any()) -> any(). -callback get(key(any()), any()) -> any().
@ -52,6 +54,27 @@
-callback from_list([{key(any()), value(any())}]) -> any(). -callback from_list([{key(any()), value(any())}]) -> any().
-callback keys(any()) -> [key(any())]. -callback keys(any()) -> [key(any())].
-else.
%% In the case where R14 or lower is being used to compile the system
%% we need to export a behaviour info
-export([behaviour_info/1]).
-spec behaviour_info(atom()) -> [{atom(), arity()}] | undefined.
behaviour_info(callbacks) ->
[{new, 0},
{has_key, 2},
{get, 2},
{add, 3},
{remove, 2},
{has_value, 2},
{size, 1},
{to_list, 1},
{from_list, 1},
{keys, 1}];
behaviour_info(_Other) ->
undefined.
-endif.
%%%=================================================================== %%%===================================================================
%%% API %%% API
%%%=================================================================== %%%===================================================================

View file

@ -1,4 +1,3 @@
%%%------------------------------------------------------------------- %%%-------------------------------------------------------------------
%%% @copyright (C) 2011, Erlware LLC %%% @copyright (C) 2011, Erlware LLC
%%% @doc %%% @doc
@ -211,14 +210,18 @@ internal_parse_version([MMP, AlphaPart, BuildPart, _]) ->
%% @doc helper function for the peg grammer to parse the iolist into a major_minor_patch %% @doc helper function for the peg grammer to parse the iolist into a major_minor_patch
-spec parse_major_minor_patch_minpatch(iolist()) -> major_minor_patch_minpatch(). -spec parse_major_minor_patch_minpatch(iolist()) -> major_minor_patch_minpatch().
parse_major_minor_patch_minpatch([MajVsn, [], [], []]) -> parse_major_minor_patch_minpatch([MajVsn, [], [], []]) ->
MajVsn; strip_maj_version(MajVsn);
parse_major_minor_patch_minpatch([MajVsn, [<<".">>, MinVsn], [], []]) -> parse_major_minor_patch_minpatch([MajVsn, [<<".">>, MinVsn], [], []]) ->
{MajVsn, MinVsn}; {strip_maj_version(MajVsn), MinVsn};
parse_major_minor_patch_minpatch([MajVsn, [<<".">>, MinVsn], [<<".">>, PatchVsn], []]) -> parse_major_minor_patch_minpatch([MajVsn,
{MajVsn, MinVsn, PatchVsn}; [<<".">>, MinVsn],
parse_major_minor_patch_minpatch([MajVsn, [<<".">>, MinVsn], [<<".">>, PatchVsn], []]) ->
[<<".">>, PatchVsn], [<<".">>, MinPatch]]) -> {strip_maj_version(MajVsn), MinVsn, PatchVsn};
{MajVsn, MinVsn, PatchVsn, MinPatch}. parse_major_minor_patch_minpatch([MajVsn,
[<<".">>, MinVsn],
[<<".">>, PatchVsn],
[<<".">>, MinPatch]]) ->
{strip_maj_version(MajVsn), MinVsn, PatchVsn, MinPatch}.
%% @doc helper function for the peg grammer to parse the iolist into an alpha part %% @doc helper function for the peg grammer to parse the iolist into an alpha part
-spec parse_alpha_part(iolist()) -> [alpha_part()]. -spec parse_alpha_part(iolist()) -> [alpha_part()].
@ -245,6 +248,14 @@ format_alpha_part([<<".">>, AlphaPart]) ->
%%%=================================================================== %%%===================================================================
%%% Internal Functions %%% Internal Functions
%%%=================================================================== %%%===================================================================
-spec strip_maj_version(iolist()) -> version_element().
strip_maj_version([<<"v">>, MajVsn]) ->
MajVsn;
strip_maj_version([[], MajVsn]) ->
MajVsn;
strip_maj_version(MajVsn) ->
MajVsn.
-spec to_list(integer() | binary() | string()) -> string() | binary(). -spec to_list(integer() | binary() | string()) -> string() | binary().
to_list(Detail) when erlang:is_integer(Detail) -> to_list(Detail) when erlang:is_integer(Detail) ->
erlang:integer_to_list(Detail); erlang:integer_to_list(Detail);
@ -308,8 +319,12 @@ internal_pes(Vsn, LVsn) ->
eql_test() -> eql_test() ->
?assertMatch(true, eql("1.0.0-alpha", ?assertMatch(true, eql("1.0.0-alpha",
"1.0.0-alpha")), "1.0.0-alpha")),
?assertMatch(true, eql("v1.0.0-alpha",
"1.0.0-alpha")),
?assertMatch(true, eql("1", ?assertMatch(true, eql("1",
"1.0.0")), "1.0.0")),
?assertMatch(true, eql("v1",
"v1.0.0")),
?assertMatch(true, eql("1.0", ?assertMatch(true, eql("1.0",
"1.0.0")), "1.0.0")),
?assertMatch(true, eql("1.0.0", ?assertMatch(true, eql("1.0.0",
@ -322,6 +337,8 @@ eql_test() ->
"1.0.0-alpha.1+build.1")), "1.0.0-alpha.1+build.1")),
?assertMatch(true, eql("1.0-alpha.1+build.1", ?assertMatch(true, eql("1.0-alpha.1+build.1",
"1.0.0.0-alpha.1+build.1")), "1.0.0.0-alpha.1+build.1")),
?assertMatch(true, eql("1.0-alpha.1+build.1",
"v1.0.0.0-alpha.1+build.1")),
?assertMatch(true, eql("aa", "aa")), ?assertMatch(true, eql("aa", "aa")),
?assertMatch(true, eql("AA.BB", "AA.BB")), ?assertMatch(true, eql("AA.BB", "AA.BB")),
?assertMatch(true, eql("BBB-super", "BBB-super")), ?assertMatch(true, eql("BBB-super", "BBB-super")),

View file

@ -1,7 +1,7 @@
semver <- major_minor_patch_min_patch ("-" alpha_part ("." alpha_part)*)? ("+" alpha_part ("." alpha_part)*)? !. semver <- major_minor_patch_min_patch ("-" alpha_part ("." alpha_part)*)? ("+" alpha_part ("." alpha_part)*)? !.
` ec_semver:internal_parse_version(Node) ` ; ` ec_semver:internal_parse_version(Node) ` ;
major_minor_patch_min_patch <- version_part ("." version_part)? ("." version_part)? ("." version_part)? ; major_minor_patch_min_patch <- ("v"? numeric_part / alpha_part) ("." version_part)? ("." version_part)? ("." version_part)? ;
version_part <- numeric_part / alpha_part ; version_part <- numeric_part / alpha_part ;