aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/diameter/src/compiler/diameter_dict_util.erl91
-rw-r--r--lib/diameter/test/diameter_compiler_SUITE.erl18
2 files changed, 34 insertions, 75 deletions
diff --git a/lib/diameter/src/compiler/diameter_dict_util.erl b/lib/diameter/src/compiler/diameter_dict_util.erl
index 51a3091883..201b153f0f 100644
--- a/lib/diameter/src/compiler/diameter_dict_util.erl
+++ b/lib/diameter/src/compiler/diameter_dict_util.erl
@@ -51,14 +51,14 @@
Opts :: list().
parse(File, Opts) ->
- put({?MODULE, verbose}, lists:member(verbose, Opts)),
+ putr(verbose, lists:member(verbose, Opts)),
try
{ok, do_parse(File, Opts)}
catch
{Reason, ?MODULE, _Line} ->
{error, Reason}
after
- erase({?MODULE, verbose})
+ eraser(verbose)
end.
%% ===========================================================================
@@ -174,12 +174,11 @@ fmt(enumerated_avp_not_defined) ->
fmt(avp_not_defined) ->
"AVP ~s referenced at line ~p neither defined nor inherited";
-fmt(beam_not_on_path) ->
- "Module ~s not found";
-
fmt(recompile) ->
"Module ~p appears to have been compiler with an incompatible "
"version of the dictionary compiler and must be recompiled";
+fmt(not_loaded) ->
+ "Module ~p is not on the code path or could not be loaded";
fmt(no_dict) ->
"Module ~p does not appear to be a diameter dictionary".
@@ -234,8 +233,8 @@ io(K, Id)
K == prefix ->
[?NL, section(K), ?SP, tok(Id)];
-io(vendor, {Id, Name}) ->
- [?NL, section(vendor) | [[?SP, tok(X)] || X <- [Id, Name]]];
+io(vendor = K, {Id, Name}) ->
+ [?NL, section(K) | [[?SP, tok(X)] || X <- [Id, Name]]];
io(avp_types = K, Body) ->
[?NL, ?NL, section(K), ?NL, [body(K,A) || A <- Body]];
@@ -252,11 +251,7 @@ io(K, Body)
K == codecs;
K == enum;
K == define ->
- if [] == Body ->
- [];
- true ->
- [[?NL, pairs(K, T)] || T <- Body]
- end.
+ [[?NL, pairs(K, T)] || T <- Body].
pairs(K, {Id, Avps}) ->
[?NL, section(K), ?SP, tok(Id), ?NL, [[?NL, body(K, A)] || A <- Avps]].
@@ -510,7 +505,7 @@ report(What, [F | A])
when is_function(F) ->
report(What, apply(F, A));
report(What, Data) ->
- report(get({?MODULE, verbose}), What, Data).
+ report(getr(verbose), What, Data).
report(true, Tag, Data) ->
io:format("##~n## ~p ~p~n", [Tag, Data]);
@@ -1114,18 +1109,16 @@ import_key({Mod, Avps}, Key) ->
%% name, Line points to the corresponding @inherit and each Avp is
%% from Mod:dict(). Lineno is 0 if the import is implicit.
-inherit(Dict, Options) ->
- Path = [D || {include, D} <- Options]
- ++ [".", code:lib_dir(diameter, ebin)],
- foldl([fun find_avps/3, Path], [], find(inherits, Dict)).
+inherit(Dict, Opts) ->
+ code:add_pathsa([D || {include, D} <- Opts]),
+ foldl(fun inherit_avps/2, [], find(inherits, Dict)).
%% Note that the module order of the returned lists is reversed
%% relative to @inherits.
-find_avps([Line, {_,_,M} | Names], Acc, Path) ->
+inherit_avps([Line, {_,_,M} | Names], Acc) ->
Mod = ?A(M),
report(inherit_from, Mod),
- Avps = avps_from_beam(find_beam(Mod, Path), Mod), %% could be empty
- case find_avps(Names, Avps) of
+ case find_avps(Names, avps_from_module(Mod)) of
{_, [{_, L, N} | _]} ->
?RETURN(requested_avp_not_found, [Mod, Line, N, L]);
{Found, []} ->
@@ -1138,9 +1131,9 @@ find_avps([], Avps) ->
%% ... or specified AVPs.
find_avps(Names, Avps) ->
- foldl(fun fa/2, {[], Names}, Avps).
+ foldl(fun acc_avp/2, {[], Names}, Avps).
-fa({Name, _Code, _Type, _Flags} = A, {Found, Not} = Acc) ->
+acc_avp({Name, _Code, _Type, _Flags} = A, {Found, Not} = Acc) ->
case lists:keyfind(Name, 3, Not) of
{_, Line, Name} ->
{[{Line, A} | Found], lists:keydelete(Name, 3, Not)};
@@ -1148,45 +1141,11 @@ fa({Name, _Code, _Type, _Flags} = A, {Found, Not} = Acc) ->
Acc
end.
-%% find_beam/2
+%% avps_from_module/2
-find_beam(Mod, Dirs)
- when is_atom(Mod) ->
- find_beam(atom_to_list(Mod), Dirs);
-find_beam(Mod, Dirs) ->
- Beam = Mod ++ code:objfile_extension(),
- case try_path(Dirs, Beam) of
- {value, Path} ->
- Path;
- false ->
- ?RETURN(beam_not_on_path, [Mod])
- end.
-
-try_path([D|Ds], Fname) ->
- Path = filename:join(D, Fname),
- case file:read_file_info(Path) of
- {ok, _} ->
- {value, Path};
- _ ->
- try_path(Ds, Fname)
- end;
-try_path([], _) ->
- false.
-
-%% avps_from_beam/2
-
-avps_from_beam(Path, Mod) ->
- report(beam, Path),
- ok = load_module(code:is_loaded(Mod), Mod, Path),
+avps_from_module(Mod) ->
orddict:fetch(avp_types, dict(Mod)).
-load_module(false, Mod, Path) ->
- R = filename:rootname(Path, code:objfile_extension()),
- {module, Mod} = code:load_abs(R),
- ok;
-load_module({file, _}, _, _) ->
- ok.
-
dict(Mod) ->
try Mod:dict() of
[?VERSION | Dict] ->
@@ -1194,8 +1153,11 @@ dict(Mod) ->
_ ->
?RETURN(recompile, [Mod])
catch
- error:_ ->
- ?RETURN(no_dict, [Mod])
+ error: _ ->
+ ?RETURN(choose(false == code:is_loaded(Mod),
+ not_loaded,
+ no_dict),
+ [Mod])
end.
%% ===========================================================================
@@ -1260,6 +1222,15 @@ avp_is_defined(Name, Dict, Line) ->
%% ===========================================================================
+putr(Key, Value) ->
+ put({?MODULE, Key}, Value).
+
+getr(Key) ->
+ get({?MODULE, Key}).
+
+eraser(Key) ->
+ erase({?MODULE, Key}).
+
choose(true, X, _) -> X;
choose(false, _, X) -> X.
diff --git a/lib/diameter/test/diameter_compiler_SUITE.erl b/lib/diameter/test/diameter_compiler_SUITE.erl
index c4de6e4f85..e2f4b3c931 100644
--- a/lib/diameter/test/diameter_compiler_SUITE.erl
+++ b/lib/diameter/test/diameter_compiler_SUITE.erl
@@ -30,8 +30,7 @@
end_per_suite/1]).
%% testcases
--export([base/1,
- format/1,
+-export([format/1,
replace/1, replace/2]).
-export([dict/0]). %% fake dictionary module
@@ -167,7 +166,7 @@
{avp_not_defined,
"CEA ::=",
"<XXX> &"},
- {beam_not_on_path,
+ {not_loaded,
[{"@avp_types", "@inherits nomod XXX &"},
{"CEA ::=", "<XXX> &"}]},
{recompile,
@@ -201,8 +200,7 @@ suite() ->
[{timetrap, {seconds, 5}}].
all() ->
- [base,
- format,
+ [format,
replace].
%% Error handling testcases will make an erroneous dictionary out of
@@ -219,16 +217,6 @@ end_per_suite(_Config) ->
%% ===========================================================================
%% testcases
-%% base/1
-
-%% This work around a minor deficiency in diameter_dict_util, that it
-%% does deal well with compiling in parallel. Load the dictionary
-%% ahead of time so that compilation doesn't.
-base(_Config) ->
- Base = filename:join([code:lib_dir(diameter, ebin),
- "diameter_gen_base_rfc3588"]),
- {module, _} = code:load_abs(Base).
-
%% Ensure that parse o format is the identity map.
format(Config) ->
Bin = proplists:get_value(base, Config),