summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFred Hebert <mononcqc@ferd.ca>2015-12-06 11:38:15 -0500
committerFred Hebert <mononcqc@ferd.ca>2015-12-06 11:59:19 -0500
commitf0876ae8c751b4083eadb81a14d000dcd59eeeb7 (patch)
treee4c331a1b6be6f49b64ac06fb2c9f2379304e745
parent5b7bf677f832311008c33a10729a9e8a6197a087 (diff)
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.
-rw-r--r--src/rebar_utils.erl25
1 files changed, 18 insertions, 7 deletions
diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl
index ea60e42..9fe22ea 100644
--- a/src/rebar_utils.erl
+++ b/src/rebar_utils.erl
@@ -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);