📄 systools_make.erl
字号:
read_application(Name, Vsn, Path, Incls, Found, FirstError); {error, _Err} -> %% Not found read_application(Name, Vsn, Path, Incls, Found, FirstError) end;read_application(Name, Vsn, [], _, true, no_fault) -> {error, {application_vsn, {Name,Vsn}}};read_application(_Name, _Vsn, [], _, true, FirstError) -> {error, FirstError};read_application(Name, _, [], _, _, no_fault) -> {error, {not_found, Name ++ ".app"}};read_application(_Name, _, [], _, _, FirstError) -> {error, FirstError}.parse_application({application, Name, Dict}, File, Vsn, Incls) when is_atom(Name), is_list(Dict) -> Items = [vsn,id,description,modules,registered, applications,included_applications,mod,start_phases,env,maxT,maxP], case catch get_items(Items, Dict) of [Vsn,Id,Desc,Mods,Regs,Apps,Incs0,Mod,Phases,Env,MaxT,MaxP] -> case override_include(Name, Incs0, Incls) of {ok, Incs} -> {ok, #application{name=Name, vsn=Vsn, id=Id, description=Desc, modules=Mods, uses=Apps, includes=Incs, regs=Regs, mod=Mod, start_phases=Phases, env=Env, maxT=MaxT, maxP=MaxP, dir=filename:dirname(File)}}; {error, IncApps} -> {error, {override_include, IncApps}} end; [OtherVsn,_,_,_,_,_,_,_,_,_,_,_] -> {error, {no_valid_version, {Vsn, OtherVsn}}}; Err -> {error, {Err, {application, Name, Dict}}} end;parse_application(Other, _, _, _) -> {error, {badly_formatted_application, Other}}.%% Test if all included applications specifed in the .rel file%% exists in the {included_applications,Incs} specified in the%% .app file.override_include(Name, Incs, Incls) -> case keysearch(Name, 1, Incls) of {value, {Name, I}} -> case specified(I, Incs) of [] -> {ok, I}; NotSpec -> {error, NotSpec} end; _ -> {ok, Incs} end.specified([App|Incls], Spec) -> case member(App, Spec) of true -> specified(Incls, Spec); _ -> [App|specified(Incls, Spec)] end;specified([], _) -> [].get_items([H|T], Dict) -> Item = check_item(keysearch(H, 1, Dict),H), [Item|get_items(T, Dict)];get_items([], _Dict) -> [].check_item({_,{mod,{M,A}}},_) when is_atom(M) -> {M,A};check_item({_,{vsn,Vsn}},I) -> case string_p(Vsn) of true -> Vsn; _ -> throw({bad_param, I}) end;check_item({_,{id,Id}},I) -> case string_p(Id) of true -> Id; _ -> throw({bad_param, I}) end;check_item({_,{description,Desc}},I) -> case string_p(Desc) of true -> Desc; _ -> throw({bad_param, I}) end;check_item({_,{applications,Apps}},I) -> case a_list_p(Apps) of true -> Apps; _ -> throw({bad_param, I}) end;check_item({_,{included_applications,Apps}},I) -> case a_list_p(Apps) of true -> Apps; _ -> throw({bad_param, I}) end;check_item({_,{registered,Regs}},I) -> case a_list_p(Regs) of true -> Regs; _ -> throw({bad_param, I}) end;check_item({_,{modules,Mods}},I) -> case mod_list_p(Mods) of true -> Mods; _ -> throw({bad_param, I}) end;check_item({_,{start_phases,Phase}},I) -> case t_list_p(Phase) of true -> Phase; _ -> throw({bad_param, I}) end;check_item({_,{env,Env}},I) -> case t_list_p(Env) of true -> Env; _ -> throw({bad_param, I}) end;check_item({_,{maxT,MaxT}},I) -> case MaxT of MaxT when is_integer(MaxT), MaxT > 0 -> MaxT; infinity -> infinity; _ -> throw({bad_param, I}) end;check_item({_,{maxP,MaxP}},I) -> case MaxP of MaxP when is_integer(MaxP), MaxP > 0 -> MaxP; infinity -> infinity; _ -> throw({bad_param, I}) end;check_item(false, included_applications) -> % optional ! [];check_item(false, mod) -> % mod is optional ! [];check_item(false, env) -> % env is optional ! [];check_item(false, id) -> % id is optional ! [];check_item(false, start_phases) -> % start_phases is optional ! undefined;check_item(false, maxT) -> % maxT is optional ! infinity;check_item(false, maxP) -> % maxP is optional ! infinity;check_item(_, Item) -> throw({missing_param, Item}).%%______________________________________________________________________%% check_applications([{{Name,Vsn},#application}]) ->%% ok | throw({error, Error})%% check that all referenced applications exists and that no%% application register processes with the same name.%% Check that included_applications are not specified as used%% in another application.check_applications(Appls) -> undef_appls(Appls), dupl_regs(Appls), %% Make a list Incs = [{Name,App,AppVsn,Dir}] Incs = [{IncApp,App,Appv,A#application.dir} || {{App,Appv},A} <- Appls, IncApp <- A#application.includes], dupl_incls(Incs), Res = add_top_apps_to_uses(Incs, Appls, []), {ok, Res}.undef_appls(Appls) -> case undefined_applications(Appls) of [] -> ok; L -> throw({error, {undefined_applications, make_set(L)}}) end.dupl_regs(Appls) -> %% Make a list Regs = [{Name,App,AppVsn,Dir}] Regs = [{Name,App,Appv,A#application.dir} || {{App,Appv},A} <- Appls, Name <- A#application.regs], case duplicates(Regs) of [] -> ok; Dups -> throw({error, {duplicate_register, Dups}}) end.dupl_incls(Incs) -> case duplicates(Incs) of [] -> ok; Dups -> throw({error, {duplicate_include, Dups}}) end.%% If an application uses another application which is included in yet%% another application, e.g. X uses A, A is included in T; then the A%% application in the X applications uses-variable is changed to the T%% application's top application to ensure the start order. %% Exception: if both X and A have the same top, then it is not%% added to avoid circular dependencies.%%%% add_top_apps_to_uses( list of all included applications in%% the system,%% list of all applications in the system,%% temporary result)%% -> new list of all applicationsadd_top_apps_to_uses(_InclApps, [], Res) -> %% InclApps = [{IncApp, App, AppVsn, Dir}] Res;add_top_apps_to_uses(InclApps, [{Name,Appl} | Appls], Res) -> MyTop = find_top_app(Appl#application.name, InclApps), F = fun(UsedApp, AccIn) when UsedApp == MyTop -> %% UW980513 This is a special case: The included app %% uses its own top app. We'll allow it, but must %% remove the top app from the uses list. AccIn -- [MyTop]; (UsedApp, AccIn) -> case lists:keysearch(UsedApp, 1, InclApps) of false -> AccIn; {value, {_,DependApp,_,_}} -> UsedAppTop = find_top_app(DependApp, InclApps), case {lists:member(UsedAppTop, AccIn), MyTop} of {true, _} -> %% the top app is already in the uses %% list, remove UsedApp AccIn -- [UsedApp]; {_, UsedAppTop} -> %% both are included in the same app AccIn; _ -> %% change the used app to the used app's %% top application AccIn1 = AccIn -- [UsedApp], AccIn1 ++ [UsedAppTop] end end end, NewUses = foldl(F, Appl#application.uses, Appl#application.uses), add_top_apps_to_uses(InclApps, Appls, Res++[{Name, Appl#application{uses = NewUses}}]).find_top_app(App, InclApps) -> case lists:keysearch(App, 1, InclApps) of false -> App; {value, {_,TopApp,_,_}} -> find_top_app(TopApp, InclApps) end. %%______________________________________________________________________%% undefined_applications([{{Name,Vsn},#application}]) ->%% [Name] list of applications that were declared in%% use declarations but are not contained in the release descriptorundefined_applications(Appls) -> Uses = append(map(fun({_,A}) -> A#application.uses ++ A#application.includes end, Appls)), Defined = map(fun({{X,_},_}) -> X end, Appls), filter(fun(X) -> not member(X, Defined) end, Uses).%%______________________________________________________________________%% sort_included_applications(Applications, Release) -> Applications%% Applications = [{{Name,Vsn},#application}]%% Release = #release{}%% %% Check that included applications are given in the same order as in%% the release resource file (.rel). Otherwise load instructions in%% the boot script, and consequently release upgrade instructions in%% relup, may end up in the wrong order.sort_included_applications(Applications, Release) when is_tuple(Release) -> {ok, sort_included_applications(Applications, Release#release.applications)};sort_included_applications([{Tuple,Appl}|Appls], OrderedAppls) -> case Appl#application.includes of Incls when length(Incls)>1 -> IndexedIncls = find_pos(Incls, OrderedAppls), SortedIndexedIncls = lists:keysort(1, IndexedIncls), Incls2 = lists:map(fun({_Index,Name}) -> Name end, SortedIndexedIncls), Appl2 = Appl#application{includes=Incls2}, [{Tuple,Appl2}|sort_included_applications(Appls, OrderedAppls)]; _Incls -> [{Tuple,Appl}|sort_included_applications(Appls, OrderedAppls)] end;sort_included_applications([], _OrderedAppls) -> [].find_pos([Name|Incs], OrderedAppls) -> [find_pos(1, Name, OrderedAppls)|find_pos(Incs, OrderedAppls)];find_pos([], _OrderedAppls) -> [].find_pos(N, Name, [{Name,_Vsn,_Type}|_OrderedAppls]) -> {N, Name};find_pos(N, Name, [_OtherAppl|OrderedAppls]) -> find_pos(N+1, Name, OrderedAppls).%%______________________________________________________________________%% check_modules(Appls, Path, TestP, Machine) ->%% {ok, Warnings} | throw({error, What})%% where Appls = [{App,Vsn}, #application}]%% performs logical checking that we can find all the modules%% etc.check_modules(Appls, Path, TestP, Machine) -> %% first check that all the module names are unique %% Make a list M1 = [{Mod,Vsn,App,AppVsn,Dir}] %% where Vsn = '$$ignore$$' | Specified M1 = [{Mod,Vsn,App,Appv,A#application.dir} || {{App,Appv},A} <- Appls, {Mod,Vsn} <- get_mod_vsn(A#application.modules)], case duplicates(M1) of [] -> case check_mods(M1, Appls, Path, TestP, Machine) of {error, Errors} -> throw({error, {modules, Errors}}); Return -> Return end; Dups ->% io:format("** ERROR Duplicate modules: ~p\n", [Dups]), throw({error, {duplicate_modules, Dups}}) end.get_mod_vsn([{Mod,Vsn}|Mods]) -> [{Mod,Vsn}|get_mod_vsn(Mods)];get_mod_vsn([Mod|Mods]) -> [{Mod,'$$ignore$$'}|get_mod_vsn(Mods)];get_mod_vsn([]) -> [].%%______________________________________________________________________%% Check that all modules exists and that the specified version%% corresponds to the version in the module's source code.%% Use the module extension of the running machine as extension for%% the checked modules.check_mods(Modules, Appls, Path, {true, XrefP}, Machine) -> Ext = objfile_extension(Machine), IncPath = create_include_path(Appls, Path), Res = append(map(fun(ModT) -> {Mod,_Vsn,App,_,Dir} = ModT, case check_mod(Mod,App,Dir,Ext,IncPath) of ok -> []; {error, Error} -> [{error,{Error, ModT}}]; {warning, Warn} -> [{warning,{Warn,ModT}}] end end, Modules)), Res2 = Res ++ check_xref(Appls, Path, XrefP), case filter(fun({error, _}) -> true; (_) -> false end, Res2) of [] -> {ok, filter(fun({warning, _}) -> true; (_) -> false end, Res2)}; Errors -> {error, Errors} end;check_mods(_, _, _, _, _) -> {ok, []}.check_xref(_Appls, _Path, false) -> [];check_xref(Appls, Path, XrefP) -> AppDirsL = [{App,A#application.dir} || {{App,_Appv},A} <- Appls], AppDirs0 = sofs:relation(AppDirsL), AppDirs = case XrefP of true -> AppDirs0; {true, Apps} -> sofs:restriction(AppDirs0, sofs:set(Apps)) end, XrefArgs = [{xref_mode, modules}], case catch xref:start(?XREF_SERVER, XrefArgs) of {ok, _Pid} -> ok; {error, {already_started, _Pid}} -> xref:stop(?XREF_SERVER), %% Clear out any previous data xref:start(?XREF_SERVER, XrefArgs) end, {ok, _} = xref:set_default(?XREF_SERVER, verbose, false), LibPath = case Path == code:get_path() of true -> code_path; % often faster false -> Path
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -