diff options
author | Anders Svensson <[email protected]> | 2013-10-04 10:57:07 +0200 |
---|---|---|
committer | Anders Svensson <[email protected]> | 2013-12-01 16:38:52 +0100 |
commit | b4b8a2130348d8828a53303d7003e24abfc692f2 (patch) | |
tree | 955fbb5ba98a40bc938811dbd039e8d9ddfb330d /lib/diameter/src/compiler/diameter_make.erl | |
parent | 350e7e93696c4a2f553a64232b5a52f256b5c0e7 (diff) | |
download | otp-b4b8a2130348d8828a53303d7003e24abfc692f2.tar.gz otp-b4b8a2130348d8828a53303d7003e24abfc692f2.tar.bz2 otp-b4b8a2130348d8828a53303d7003e24abfc692f2.zip |
Fix diameter_make:flatten/1
To set @avp_vendor_id, @codecs and @custom_types as required for
imported avps.
Diffstat (limited to 'lib/diameter/src/compiler/diameter_make.erl')
-rw-r--r-- | lib/diameter/src/compiler/diameter_make.erl | 96 |
1 files changed, 87 insertions, 9 deletions
diff --git a/lib/diameter/src/compiler/diameter_make.erl b/lib/diameter/src/compiler/diameter_make.erl index 411d71ba3b..99034734c5 100644 --- a/lib/diameter/src/compiler/diameter_make.erl +++ b/lib/diameter/src/compiler/diameter_make.erl @@ -107,19 +107,97 @@ format([?VERSION | Dict]) -> -> parsed(). flatten([?VERSION = V | Dict]) -> - [V | lists:foldl(fun flatten/2, Dict, [[avp_types, import_avps], - [grouped, import_groups], - [enum, import_enums]])]. + [V | lists:foldl(fun flatten/2, + Dict, + [avp_vendor_id, + custom_types, + codecs, + [avp_types, import_avps], + [grouped, import_groups], + [enum, import_enums]])]. + +%% =========================================================================== + +%% flatten/2 flatten([_,_] = Keys, Dict) -> [Values, Imports] = [orddict:fetch(K, Dict) || K <- Keys], - Vs = lists:append([Values | [V || {_,V} <- Imports]]), - lists:foldl(fun store/2, + Vs = lists:append([Values | [V || {_Mod, V} <- Imports]]), + lists:foldl(fun({K,V},D) -> orddict:store(K,V,D) end, Dict, - lists:zip([inherits | Keys], [[], Vs, []])). - -store({Key, Value}, Dict) -> - orddict:store(Key, Value, Dict). + lists:zip([inherits | Keys], [[], Vs, []])); + +%% Inherited avp's setting the 'V' flag get their value either from +%% @avp_vendor_id in the inheriting dictionary or from @vendor in the +%% *inherited* (not inheriting) dictionary: add the latter to +%% @avp_vendor_id as required. +flatten(avp_vendor_id = Key, Dict) -> + Def = orddict:find(vendor, Dict), + ModD = imports(Dict), + Vids = orddict:fetch(Key, Dict), + Avps = lists:append([As || {_,As} <- Vids]), + orddict:store(Key, + dict:fold(fun(M, As, A) -> vid(M, As -- Avps, Def, A) end, + Vids, + ModD), + Dict); + +%% Import @codecs and @custom_types from inherited dictionaries as +%% required. +flatten(Key, Dict) -> + ImportAvps = orddict:fetch(import_avps, Dict), + ImportItems = [{M, As} + || {Mod, Avps} <- ImportAvps, + [_|D] <- [Mod:dict()], + {M,As0} <- orddict:fetch(Key, D), + F <- [fun(A) -> lists:keymember(A, 1, Avps) end], + [_|_] = As <- [lists:filter(F, As0)]], + orddict:store(Key, + lists:foldl(fun merge/2, + orddict:fetch(Key, Dict), + ImportItems), + Dict). + +%% merge/2 + +merge({Mod, _Avps} = T, Acc) -> + merge(lists:keyfind(Mod, 1, Acc), T, Acc). + +merge({Mod, Avps}, {Mod, As}, Acc) -> + lists:keyreplace(Mod, 1, Acc, {Mod, Avps ++ As}); +merge(false, T, Acc) -> + [T | Acc]. + +%% imports/1 +%% +%% Return a module() -> [AVP] dict of inherited AVP's setting the V flag. + +imports(Dict) -> + lists:foldl(fun imports/2, + dict:new(), + orddict:fetch(import_avps, Dict)). + +imports({Mod, Avps}, Dict) -> + dict:store(Mod, + [A || {A,_,_,Fs} <- Avps, lists:member($V, Fs)], + Dict). + +%% vid/4 + +vid(_, [], _, Acc) -> + Acc; +vid(Mod, Avps, Def, Acc) -> + v(Mod:vendor_id(), Avps, Def, Acc). + +v(Vid, _, {ok, {Vid, _}}, Acc) -> %% same id as inheriting dictionary's + Acc; +v(Vid, Avps, _, Acc) -> + case lists:keyfind(Vid, 1, Acc) of + {Vid, As} -> + lists:keyreplace(Vid, 1, Acc, {Vid, As ++ Avps}); + false -> + [{Vid, Avps} | Acc] + end. %% =========================================================================== |