aboutsummaryrefslogtreecommitdiffstats
path: root/lib/dialyzer/test/small_tests_SUITE_data/src/appmon_place.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dialyzer/test/small_tests_SUITE_data/src/appmon_place.erl')
-rw-r--r--lib/dialyzer/test/small_tests_SUITE_data/src/appmon_place.erl71
1 files changed, 71 insertions, 0 deletions
diff --git a/lib/dialyzer/test/small_tests_SUITE_data/src/appmon_place.erl b/lib/dialyzer/test/small_tests_SUITE_data/src/appmon_place.erl
new file mode 100644
index 0000000000..8371cab233
--- /dev/null
+++ b/lib/dialyzer/test/small_tests_SUITE_data/src/appmon_place.erl
@@ -0,0 +1,71 @@
+%%---------------------------------------------------------------------
+%% This is added as a test because it was giving a false positive
+%% (function move/4 will nevr be called) due to the strange use of
+%% self-recursive fun construction in placex/3.
+%%
+%% The analysis was getting confused that the foldl call will never
+%% terminate (due to a wrong hard-coded type for foldl) and inferred
+%% that the remaining calls in the body of placex/3 will not be
+%% reached. Fixed 11 March 2005.
+%%---------------------------------------------------------------------
+
+-module(appmon_place).
+-export([place/2]).
+
+place(DG, Root) ->
+ case appmon_dg:get(data, DG, Root) of
+ false -> [0];
+ _Other ->
+ placey(DG, Root, 1),
+ placex(DG, Root, [])
+ end.
+
+placey(DG, V, Y) ->
+ appmon_dg:set(y, DG, V, Y),
+ Y1 = Y+1,
+ lists:foreach(fun(C) -> placey(DG, C, Y1) end, appmon_dg:get(out, DG, V)).
+
+placex(DG, V, LastX) ->
+ Ch = appmon_dg:get(out, DG, V),
+ ChLX = lists:foldl(fun(C, Accu) -> placex(DG, C, Accu) end,
+ tll(LastX),
+ Ch),
+ Width = appmon_dg:get(w, DG, V),
+ MyX = calc_mid(DG, Width, Ch),
+ DeltaX = calc_delta(MyX, hdd(LastX)+20),
+ appmon_dg:set(x, DG, V, MyX),
+ move(DG, V, [MyX+Width | ChLX], DeltaX).
+
+move(_DG, _L, LastX, 0) -> LastX;
+move(DG, V, LastX, DeltaX) -> move2(DG, V, LastX, DeltaX).
+
+move2(DG, V, LastX, DeltaX) ->
+ NewX = appmon_dg:get(x, DG, V)+DeltaX,
+ appmon_dg:set(x, DG, V, NewX),
+ ChLX = lists:foldl(fun(C, LX) -> move2(DG, C, LX, DeltaX) end,
+ tll(LastX),
+ appmon_dg:get(out, DG, V)),
+ [max(NewX+appmon_dg:get(w, DG, V), hdd(LastX)) | ChLX].
+
+max(A, B) when A>B -> A;
+max(_, B) -> B.
+
+calc_mid(_DG, _Width, []) -> 0;
+calc_mid(DG, Width, ChList) ->
+ LeftMostX = appmon_dg:get(x, DG, hd(ChList)),
+ Z2 = lists:last(ChList),
+ RightMostX = appmon_dg:get(x, DG, Z2)+appmon_dg:get(w, DG, Z2),
+ trunc((LeftMostX+RightMostX)/2)-trunc(Width/2).
+
+calc_delta(Mid, Right) ->
+ if Right>Mid -> Right-Mid;
+ true -> 0
+ end.
+
+%% Special head and tail
+%% Handles empty list in a non-standard way
+tll([]) -> [];
+tll([_|T]) -> T.
+hdd([]) -> 0;
+hdd([H|_]) -> H.
+