summaryrefslogtreecommitdiff
path: root/lib/dialyzer/test/small_SUITE_data/src/appmon_place.erl
blob: 60ffbe818fe65809a449b96b3c983e4f6580107b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
%%---------------------------------------------------------------------
%% 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.