aboutsummaryrefslogtreecommitdiffstats
path: root/lib/dialyzer/test/opaque_SUITE_data/src/crash/crash_1.erl
blob: eebeed15af5a03e42abb0c88e54988a69970320e (plain) (blame)
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
%%%-------------------------------------------------------------------
%%% From : Fredrik Thulin <[email protected]>
%%%
%%% A module with an erroneous record field declaration which mixes up
%%% structured and opaque terms and causes a crash in dialyzer.
%%%
%%% In addition, it revealed that the compiler produced extraneous
%%% warnings about unused record definitions when in fact they are
%%% needed for type declarations. This is now fixed.
%%%-------------------------------------------------------------------
-module(crash_1).

-export([add/3, empty/0]).

%%--------------------------------------------------------------------

-record(sipurl,  {proto = "sip" :: string(), host :: string()}).
-record(keylist, {list = [] :: [_]}).
-type sip_headers() :: #keylist{}.
-record(request, {uri :: #sipurl{}, header :: sip_headers()}).
-type sip_request() :: #request{}.

%%--------------------------------------------------------------------

-record(target, {branch	:: string(), request :: sip_request()}).
-opaque target() :: #target{}.

-record(targetlist, {list :: target()}).  % XXX: THIS ONE SHOULD READ [target()]
-opaque targetlist() :: #targetlist{}.

%%====================================================================

add(Branch, #request{} = Request, #targetlist{list = L} = TargetList) ->
    case get_using_branch(Branch, TargetList) of
	none ->
	    NewTarget = #target{branch = Branch, request = Request},
	    #targetlist{list = L ++ [NewTarget]};
	#target{} ->
	    TargetList
    end.

-spec empty() -> targetlist().

empty() ->
    #targetlist{list = []}.

get_using_branch(Branch, #targetlist{list = L}) when is_list(Branch) ->
    get_using_branch2(Branch, L).

get_using_branch2(_Branch, []) ->
    none;
get_using_branch2(Branch, [#target{branch=Branch}=H | _T]) ->
    H;
get_using_branch2(Branch, [#target{} | T]) ->
    get_using_branch2(Branch, T).