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).
|