Browse Source

Fix tuple umerging

- proper segregation of comparison between tuple terms and non-tuple
  terms. Guards weren't specific enough and that meant the wrong clauses
  of guards would be triggered
- proper deduplication of entries in the list. An additional N passes
  are required (we co-opt the reverse step to be more efficient) because
  while the original lists:umerge easily removes dupes, this is
  requiring more logic here since `[a,{a,b},{a,b,c},a,{a,b,c}]` is a
  possible interleaving and we'd want `[a,{a,b},{a,b,c}]` -- comparison
  of direct neighbours isn't enough.
pull/963/head
Fred Hebert 9 years ago
parent
commit
f0876ae8c7
1 changed files with 18 additions and 7 deletions
  1. +18
    -7
      src/rebar_utils.erl

+ 18
- 7
src/rebar_utils.erl View File

@ -285,7 +285,18 @@ tup_umerge(NewList, OldList) ->
tup_umerge_([], Olds) ->
Olds;
tup_umerge_([New|News], Olds) ->
lists:reverse(umerge(News, Olds, [], New)).
tup_umerge_dedup_(umerge(News, Olds, [], New), []).
%% removes 100% identical duplicate elements so that
%% `[a,{a,b},a,{a,c},a]' returns `[a,{a,b},{a,c}]'.
%% Operates on a reverted list that gets reversed as part of this pass
tup_umerge_dedup_([], Acc) ->
Acc;
tup_umerge_dedup_([H|T], Acc) ->
case lists:member(H,T) of
true -> tup_umerge_dedup_(T, Acc);
false -> tup_umerge_dedup_(T, [H|Acc])
end.
tup_find(_Elem, []) ->
false;
@ -304,9 +315,9 @@ tup_find(Elem, [_Elem | Elems]) ->
%% This is equivalent to umerge2_2 in the stdlib, except we use the expanded
%% value/key only to compare
umerge(News, [Old|Olds], Merged, Cmp) when element(1, Cmp) == element(1, Old);
element(1, Cmp) == Old;
Cmp == element(1, Old);
Cmp =< Old ->
element(1, Cmp) == Old andalso not is_tuple(Old);
Cmp == element(1, Old) andalso not is_tuple(Cmp);
Cmp =< Old andalso not is_tuple(Cmp) andalso not is_tuple(Old) ->
umerge(News, Olds, [Cmp | Merged], Cmp, Old);
umerge(News, [Old|Olds], Merged, Cmp) ->
umerge(News, Olds, [Old | Merged], Cmp);
@ -320,9 +331,9 @@ umerge(News, [], Merged, Cmp) ->
umerge([New|News], Olds, Merged, CmpMerged, Cmp) when CmpMerged == Cmp ->
umerge(News, Olds, Merged, New);
umerge([New|News], Olds, Merged, _CmpMerged, Cmp) when element(1,New) == element(1, Cmp);
element(1,New) == Cmp;
New == element(1, Cmp);
New =< Cmp ->
element(1,New) == Cmp andalso not is_tuple(Cmp);
New == element(1, Cmp) andalso not is_tuple(New);
New =< Cmp andalso not is_tuple(New) andalso not is_tuple(Cmp) ->
umerge(News, Olds, [New | Merged], New, Cmp);
umerge([New|News], Olds, Merged, _CmpMerged, Cmp) -> % >
umerge(News, Olds, [Cmp | Merged], New);

Loading…
Cancel
Save