diff options
author | Anders Svensson <[email protected]> | 2011-12-03 17:53:15 +0100 |
---|---|---|
committer | Anders Svensson <[email protected]> | 2011-12-04 17:47:48 +0100 |
commit | 22f9111ef12ed58aeb5a15ed55a983c9b19cddb8 (patch) | |
tree | d20531044fc7ffabb4155a94d4c11c093bc24ea1 | |
parent | 23dbc347fe872f953d0f146ecb87ddc34ea608d7 (diff) | |
download | otp-22f9111ef12ed58aeb5a15ed55a983c9b19cddb8.tar.gz otp-22f9111ef12ed58aeb5a15ed55a983c9b19cddb8.tar.bz2 otp-22f9111ef12ed58aeb5a15ed55a983c9b19cddb8.zip |
Don't explicitly load inherited modules
Just use include options to add to the code path and expect that
dependent modules will either already have been loaded or will be
loaded dynamically, thereby avoiding having a module being left as
both current and old code when compiling concurrently. Not a problem
for a human user interactively compiling one module at a time
but the compiler test suite for one will compile concurrently.
In any case, leaving behind old code is probably not what someone
would expect while relying on the code path probably is.
-rw-r--r-- | lib/diameter/src/compiler/diameter_dict_util.erl | 91 | ||||
-rw-r--r-- | lib/diameter/test/diameter_compiler_SUITE.erl | 18 |
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), |