diff options
Diffstat (limited to 'lib/reltool/src')
-rw-r--r-- | lib/reltool/src/Makefile | 9 | ||||
-rw-r--r-- | lib/reltool/src/reltool.erl | 4 | ||||
-rw-r--r-- | lib/reltool/src/reltool_app_win.erl | 12 | ||||
-rw-r--r-- | lib/reltool/src/reltool_fgraph_win.erl | 4 | ||||
-rw-r--r-- | lib/reltool/src/reltool_mod_win.erl | 75 | ||||
-rw-r--r-- | lib/reltool/src/reltool_server.erl | 180 | ||||
-rw-r--r-- | lib/reltool/src/reltool_sys_win.erl | 132 | ||||
-rw-r--r-- | lib/reltool/src/reltool_target.erl | 134 | ||||
-rw-r--r-- | lib/reltool/src/reltool_utils.erl | 41 |
9 files changed, 345 insertions, 246 deletions
diff --git a/lib/reltool/src/Makefile b/lib/reltool/src/Makefile index a7e34053f1..b8387fff96 100644 --- a/lib/reltool/src/Makefile +++ b/lib/reltool/src/Makefile @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2009-2012. All Rights Reserved. +# Copyright Ericsson AB 2009-2013. All Rights Reserved. # # The contents of this file are subject to the Erlang Public License, # Version 1.1, (the "License"); you may not use this file except in @@ -57,7 +57,8 @@ APPUP_TARGET = $(EBIN)/$(APPUP_FILE) # ---------------------------------------------------- ERL_COMPILE_FLAGS += +'{parse_transform,sys_pre_attributes}' \ - +'{attribute,insert,app_vsn,$(APP_VSN)}' + +'{attribute,insert,app_vsn,$(APP_VSN)}' \ + -Werror # ---------------------------------------------------- # Targets @@ -79,10 +80,10 @@ docs: # ---------------------------------------------------- $(APP_TARGET): $(APP_SRC) ../vsn.mk - sed -e 's;%VSN%;$(VSN);' $< > $@ + $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@ $(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk - sed -e 's;%VSN%;$(VSN);' $< > $@ + $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@ # ---------------------------------------------------- # Dependencies diff --git a/lib/reltool/src/reltool.erl b/lib/reltool/src/reltool.erl index 2bdf222aa0..8ab2c2399e 100644 --- a/lib/reltool/src/reltool.erl +++ b/lib/reltool/src/reltool.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2009-2012. All Rights Reserved. +%% Copyright Ericsson AB 2009-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -120,7 +120,7 @@ apply_fun(Pid, false, Fun) -> apply_fun(Pid, true, Fun) -> case get_status(Pid) of {ok, Warnings} -> - [io:format("~p: ~s\n", [?APPLICATION, W]) || W <- Warnings], + [io:format("~w: ~ts\n", [?APPLICATION, W]) || W <- Warnings], apply_fun(Pid, false, Fun); {error, _Reason} = Error -> stop(Pid), diff --git a/lib/reltool/src/reltool_app_win.erl b/lib/reltool/src/reltool_app_win.erl index 6cd0d2f90b..81ab1687fb 100644 --- a/lib/reltool/src/reltool_app_win.erl +++ b/lib/reltool/src/reltool_app_win.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2009-2012. All Rights Reserved. +%% Copyright Ericsson AB 2009-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -173,7 +173,7 @@ loop(#state{xref_pid = Xref, common = C, app = App} = S) -> S#state.mod_wins)}, ?MODULE:loop(S2); Msg -> - error_logger:format("~p~p got unexpected message:\n\t~p\n", + error_logger:format("~w~w got unexpected message:\n\t~p\n", [?MODULE, self(), Msg]), ?MODULE:loop(S) end. @@ -181,7 +181,7 @@ loop(#state{xref_pid = Xref, common = C, app = App} = S) -> exit_warning({'EXIT', _Pid, shutdown}) -> ok; exit_warning({'EXIT', _Pid, _Reason} = Msg) -> - error_logger:format("~p~p got unexpected message:\n\t~p\n", + error_logger:format("~w~w got unexpected message:\n\t~p\n", [?MODULE, self(), Msg]). create_window(#state{app = App} = S) -> @@ -627,7 +627,7 @@ handle_event(#state{sys = Sys, app = App} = S, Wx) -> Items = reltool_utils:get_items(ListCtrl), handle_mod_button(S, Items, Action); _ -> - error_logger:format("~p~p got unexpected app event from " + error_logger:format("~w~w got unexpected app event from " "wx:\n\t~p\n", [?MODULE, self(), Wx]), S @@ -674,8 +674,8 @@ move_mod(App, {_ItemNo, ModStr}, Action) -> blacklist_del -> undefined; _ -> - error_logger:format("~p~p got unexpected mod " - "button event: ~p\n\t ~p\n", + error_logger:format("~w~w got unexpected mod " + "button event: ~w\n\t ~p\n", [?MODULE, self(), ModName, Action]), M#mod.incl_cond end, diff --git a/lib/reltool/src/reltool_fgraph_win.erl b/lib/reltool/src/reltool_fgraph_win.erl index b0deb1bab2..66bc2b5ab3 100644 --- a/lib/reltool/src/reltool_fgraph_win.erl +++ b/lib/reltool/src/reltool_fgraph_win.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2009-2010. All Rights Reserved. +%% Copyright Ericsson AB 2009-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -525,7 +525,7 @@ loop(S, G) -> exit(Reason); Other -> - error_logger:format("~p~p got unexpected message:\n\t~p\n", + error_logger:format("~w~w got unexpected message:\n\t~p\n", [?MODULE, self(), Other]), loop(S, G) end. diff --git a/lib/reltool/src/reltool_mod_win.erl b/lib/reltool/src/reltool_mod_win.erl index 899423bb6d..b0193a2ae4 100644 --- a/lib/reltool/src/reltool_mod_win.erl +++ b/lib/reltool/src/reltool_mod_win.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2009-2012. All Rights Reserved. +%% Copyright Ericsson AB 2009-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -130,7 +130,7 @@ do_init(Parent, WxEnv, Xref, RelPid, C, ModName) -> loop(#state{xref_pid = Xref, common = C, mod = Mod} = S) -> receive Msg -> - %% io:format("~s~p -> ~p\n", [S#state.name, self(), Msg]), + %% io:format("~ts~w -> ~p\n", [S#state.name, self(), Msg]), case Msg of {system, From, SysMsg} -> Dbg = C#common.sys_debug, @@ -170,7 +170,7 @@ loop(#state{xref_pid = Xref, common = C, mod = Mod} = S) -> S2 = handle_event(S, Wx), ?MODULE:loop(S2); _ -> - error_logger:format("~p~p got unexpected message:\n\t~p\n", + error_logger:format("~w~w got unexpected message:\n\t~p\n", [?MODULE, self(), Msg]), ?MODULE:loop(S) end @@ -335,23 +335,37 @@ find_regular_bin(App, Mod) -> SrcDir = filename:join([ActiveDir, "src"]), ModStr = atom_to_list(Mod#mod.name), Base = "^" ++ ModStr ++ "\\.erl$", - Find = fun(F, _Acc) -> throw(file:read_file(F)) end, + Find = fun(F, _Acc) -> throw({file:read_file(F),epp:read_encoding(F)}) end, case catch filelib:fold_files(SrcDir, Base, true, Find, {error, enoent}) of - {ok, Bin} -> - Bin; + {{ok, Bin},Encoding0} -> + Encoding = + case Encoding0 of + none -> epp:default_encoding(); + _ -> Encoding0 + end, + unicode:characters_to_binary(Bin,Encoding,utf8); {error, enoent} -> %% Reconstructing the source code from debug info if possible BeamFile = filename:join([ActiveDir, "ebin", ModStr ++ ".beam"]), - case beam_lib:chunks(BeamFile, [abstract_code]) of - {ok,{_,[{abstract_code,{_,AC}}]}} -> - IoList = erl_prettypr:format(erl_syntax:form_list(AC)), - list_to_binary(IoList); - _ -> - list_to_binary(["%% Bad luck, cannot find any " - "debug info in the file \"", BeamFile]) + case source_from_beam(BeamFile) of + {ok,Source} -> + Source; + error -> + unicode:characters_to_binary( + ["%% Bad luck, cannot find any " + "debug info in the file \"", BeamFile]) end end. +source_from_beam(Beam) -> + case beam_lib:chunks(Beam, [abstract_code]) of + {ok,{_,[{abstract_code,{_,AC}}]}} -> + IoList = [erl_pp:form(F,[{encoding,utf8}]) || F <- AC], + {ok,unicode:characters_to_binary(IoList)}; + _ -> + error + end. + find_escript_bin(#app{active_dir = ActiveDir}, Mod) -> NotFound = false, ModName = Mod#mod.name, @@ -366,16 +380,10 @@ find_escript_bin(#app{active_dir = ActiveDir}, Mod) -> case beam_lib:version(Bin) of {ok,{M, _}} when M =:= ModName; FullName =:= "." -> - case beam_lib:chunks(Bin, - [abstract_code]) of - {ok,{_,[{abstract_code,{_,AC}}]}} -> - Form = - erl_syntax:form_list(AC), - IoList = - erl_prettypr:format(Form), - {obj, - list_to_binary(IoList)}; - _ -> + case source_from_beam(Bin) of + {ok,Source} -> + {obj,Source}; + error -> Acc end; _ -> @@ -396,12 +404,9 @@ find_escript_bin(#app{active_dir = ActiveDir}, Mod) -> case filename:split(FullName) of [_AppName, "ebin", F] when F =:= ObjFile, Acc =:= NotFound -> - case beam_lib:chunks(GetBin(), - [abstract_code]) of - {ok,{_,[{abstract_code,{_,AC}}]}} -> - Form = erl_syntax:form_list(AC), - IoList = erl_prettypr:format(Form), - {obj, list_to_binary(IoList)}; + case source_from_beam(GetBin()) of + {ok,Source} -> + {obj,Source}; _ -> Acc end; @@ -420,13 +425,15 @@ find_escript_bin(#app{active_dir = ActiveDir}, Mod) -> {ok, {obj, Bin}} -> Bin; _ -> - list_to_binary(["%% Bad luck, cannot find the " - "code in the escript ", Escript, "."]) + unicode:characters_to_binary( + ["%% Bad luck, cannot find the " + "code in the escript ", Escript, "."]) end catch throw:Reason when is_list(Reason) -> - list_to_binary(["%% Bad luck, cannot find the code " - "in the escript ", Escript, ": ", Reason]) + unicode:characters_to_binary( + ["%% Bad luck, cannot find the code " + "in the escript ", Escript, ": ", Reason]) end. create_config_page(S) -> @@ -478,7 +485,7 @@ handle_event(#state{xref_pid = Xref} = S, Wx) -> wxWindow:setFocus(ObjRef), S; _ -> - error_logger:format("~p~p got unexpected mod event from " + error_logger:format("~w~w got unexpected mod event from " "wx:\n\t~p\n", [?MODULE, self(), Wx]), S diff --git a/lib/reltool/src/reltool_server.erl b/lib/reltool/src/reltool_server.erl index 3d1d7e54bf..5e25f22a6f 100644 --- a/lib/reltool/src/reltool_server.erl +++ b/lib/reltool/src/reltool_server.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2009-2012. All Rights Reserved. +%% Copyright Ericsson AB 2009-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -399,12 +399,12 @@ loop(#state{sys = Sys} = S) -> {'EXIT', Pid, Reason} when Pid =:= S#state.parent_pid -> exit(Reason); {call, ReplyTo, Ref, Msg} when is_pid(ReplyTo), is_reference(Ref) -> - error_logger:format("~p~p got unexpected call:\n\t~p\n", + error_logger:format("~w~w got unexpected call:\n\t~p\n", [?MODULE, self(), Msg]), reltool_utils:reply(ReplyTo, Ref, {error, {invalid_call, Msg}}), ?MODULE:loop(S); Msg -> - error_logger:format("~p~p got unexpected message:\n\t~p\n", + error_logger:format("~w~w got unexpected message:\n\t~p\n", [?MODULE, self(), Msg]), ?MODULE:loop(S) end. @@ -422,7 +422,7 @@ do_set_apps(#state{sys = Sys} = S, ChangedApps) -> %% 2) removing #app records if no configurable fields are set %% 3) keeping #app records that are not changed app_update_config([#app{name=Name,is_escript={inlined,Escript}}|_],_SysApps) -> - reltool_utils:throw_error("Application ~p is inlined in ~p. Can not change " + reltool_utils:throw_error("Application ~w is inlined in ~w. Can not change " "configuration for an inlined application.", [Name,Escript]); app_update_config([Config|Configs],SysApps) -> @@ -580,8 +580,8 @@ apps_in_rel(#rel{name = RelName, rel_apps = RelApps}, Apps) -> IA; false -> reltool_utils:throw_error( - "Release ~p uses non existing " - "application ~p", + "Release ~tp uses non existing " + "application ~w", [RelName,RA#rel_app.name]) end; IA -> @@ -602,7 +602,7 @@ more_apps_in_rels([{RelName, AppName} = RA | RelApps], Apps, Acc) -> more_apps_in_rels(RelApps, Apps, Acc2); false -> reltool_utils:throw_error( - "Release ~p uses non existing application ~p", + "Release ~tp uses non existing application ~w", [RelName,AppName]) end end; @@ -640,7 +640,7 @@ app_init_is_included(#state{app_tab = AppTab, mod_tab = ModTab, sys=Sys}, {undefined, false, false, Status}; {exclude, [RelName | _]} -> % App is included in at least one rel reltool_utils:throw_error( - "Application ~p is used in release ~p and cannot be excluded", + "Application ~w is used in release ~tp and cannot be excluded", [AppName,RelName]); {derived, []} -> {undefined, undefined, undefined, Status}; @@ -665,7 +665,7 @@ app_init_is_included(#state{app_tab = AppTab, mod_tab = ModTab, sys=Sys}, Status3. mod_init_is_included(ModTab, M, ModCond, AppCond, Default, Status) -> - %% print(M#mod.name, hipe, "incl_cond -> ~p\n", [AppCond]), + %% print(M#mod.name, hipe, "incl_cond -> ~w\n", [AppCond]), IsIncl = case AppCond of include -> @@ -674,8 +674,10 @@ mod_init_is_included(ModTab, M, ModCond, AppCond, Default, Status) -> true; exclude -> false; + derived -> + undefined; undefined -> - %% print(M#mod.name, hipe, "mod_cond -> ~p\n", + %% print(M#mod.name, hipe, "mod_cond -> ~w\n", %% [ModCond]), case ModCond of all -> true; @@ -693,6 +695,8 @@ mod_init_is_included(ModTab, M, ModCond, AppCond, Default, Status) -> true; exclude -> false; + derived -> + undefined; undefined -> Default end @@ -707,23 +711,23 @@ mod_init_is_included(ModTab, M, ModCond, AppCond, Default, Status) -> {false,_} -> ets:insert(ModTab, M2), reltool_utils:add_warning( - "Module ~p exists in applications ~p and ~p. " - "Using module from application ~p.", + "Module ~w exists in applications ~w and ~w. " + "Using module from application ~w.", [M#mod.name, Existing#mod.app_name, M#mod.app_name, M#mod.app_name], Status); {_,false} -> %% Don't insert in ModTab - using Existing reltool_utils:add_warning( - "Module ~p exists in applications ~p and ~p. " - "Using module from application ~p.", + "Module ~w exists in applications ~w and ~w. " + "Using module from application ~w.", [M#mod.name, Existing#mod.app_name, M#mod.app_name,Existing#mod.app_name], Status); {_,_} -> reltool_utils:throw_error( - "Module ~p potentially included by two different " - "applications: ~p and ~p.", + "Module ~w potentially included by two different " + "applications: ~w and ~w.", [M#mod.name,Existing#mod.app_name,M#mod.app_name]) end; [] -> @@ -731,7 +735,7 @@ mod_init_is_included(ModTab, M, ModCond, AppCond, Default, Status) -> Status end, - %% print(M#mod.name, hipe, "~p -> ~p\n", [M2, IsIncl]), + %% print(M#mod.name, hipe, "~p -> ~w\n", [M2, IsIncl]), {M2,Status2}. false_to_undefined(Bool) -> @@ -783,9 +787,10 @@ mod_mark_is_included(#state{app_tab=AppTab, mod_tab=ModTab, sys=Sys} = S, M#mod{is_pre_included = true, is_included = true}; exclude -> - M#mod{is_pre_included = true, - is_included = true}; - undefined -> + M#mod{is_pre_included = false, + is_included = false}; + ModInclCond when ModInclCond==undefined; + ModInclCond==derived -> M#mod{is_included = true} end, ets:insert(ModTab, M2), @@ -883,7 +888,7 @@ mod_recap_dependencies(S, A, [#mod{name = ModName}=M1 | Mods], Acc, IsIncl) -> case ets:lookup(S#state.mod_tab, ModName) of [M2] when M2#mod.app_name=:=A#app.name -> ModStatus = do_get_status(M2), - %% print(M2#mod.name, hipe, "status -> ~p\n", [ModStatus]), + %% print(M2#mod.name, hipe, "status -> ~w\n", [ModStatus]), {IsIncl2, M3} = case M2#mod.is_included of true -> @@ -905,8 +910,8 @@ mod_recap_dependencies(S, A, [#mod{name = ModName}=M1 | Mods], Acc, IsIncl) -> %% A module is potensially included by multiple %% applications. This is not allowed! reltool_utils:throw_error( - "Module ~p potentially included by two different applications: " - "~p and ~p", [ModName,A#app.name, " and ", M2#mod.app_name, "."]) + "Module ~w potentially included by two different applications: " + "~w and ~w.", [ModName,A#app.name, M2#mod.app_name]) end; mod_recap_dependencies(_S, _A, [], Acc, IsIncl) -> {lists:reverse(Acc), IsIncl}. @@ -934,7 +939,7 @@ verify_config(#state{app_tab=AppTab, sys=#sys{boot_rel = BootRel, rels = Rels}}, Rels); false -> reltool_utils:throw_error( - "Release ~p is mandatory (used as boot_rel)",[BootRel]) + "Release ~tp is mandatory (used as boot_rel)",[BootRel]) end. check_app(AppTab, {RelName, AppName}, Status) -> @@ -944,7 +949,7 @@ check_app(AppTab, {RelName, AppName}, Status) -> Status; _ -> reltool_utils:throw_error( - "Release ~p uses non included application ~p",[RelName,AppName]) + "Release ~tp uses non included application ~w",[RelName,AppName]) end. check_rel(RelName, RelApps, Status) -> @@ -955,8 +960,8 @@ check_rel(RelName, RelApps, Status) -> Acc; false -> reltool_utils:throw_error( - "Mandatory application ~p is not included in " - "release ~p", [AppName,RelName]) + "Mandatory application ~w is not included in " + "release ~tp", [AppName,RelName]) end end, Mandatory = [kernel, stdlib], @@ -979,7 +984,7 @@ refresh_app(#app{name = AppName, %% Add info from .app file Base = get_base(AppName, ActiveDir), - {_, DefaultVsn} = reltool_utils:split_app_name(Base), + DefaultVsn = get_vsn_from_dir(AppName,Base), Ebin = filename:join([ActiveDir, "ebin"]), AppFile = filename:join([Ebin, @@ -1010,8 +1015,8 @@ refresh_app(#app{name = AppName, lists:foldl( fun(M,S) -> reltool_utils:add_warning( - "Module ~p duplicated in app file for " - "application ~p.", [M, AppName], S) + "Module ~w duplicated in app file for " + "application ~w.", [M, AppName], S) end, Status3, DuplicatedMods) @@ -1069,18 +1074,18 @@ read_app_info(AppFileOrBin, AppFile, AppName, DefaultVsn, Status) -> parse_app_info(AppFile, Info, AI, Status); {ok, _BadApp} -> {missing_app_info(DefaultVsn), - reltool_utils:add_warning("~p: Illegal contents in app file ~p, " + reltool_utils:add_warning("~w: Illegal contents in app file ~tp, " "application tuple with arity 3 expected.", [AppName,AppFile], Status)}; {error, Text} when Text =:= EnoentText -> {missing_app_info(DefaultVsn), - reltool_utils:add_warning("~p: Missing app file ~p.", + reltool_utils:add_warning("~w: Missing app file ~tp.", [AppName,AppFile], Status)}; {error, Text} -> {missing_app_info(DefaultVsn), - reltool_utils:add_warning("~p: Cannot parse app file ~p (~p).", + reltool_utils:add_warning("~w: Cannot parse app file ~tp (~tp).", [AppName,AppFile,Text], Status)} end. @@ -1117,7 +1122,7 @@ parse_app_info(File, [{Key, Val} | KeyVals], AI, Status) -> Status); _ -> Status2 = - reltool_utils:add_warning("Unexpected item ~p in app file ~p.", + reltool_utils:add_warning("Unexpected item ~p in app file ~tp.", [Key,File], Status), parse_app_info(File, KeyVals, AI, Status2) @@ -1207,7 +1212,7 @@ wait_for_processto_die(Ref, Pid, File) -> {'DOWN', Ref, _Type, _Object, _Info} -> ok after timer:seconds(30) -> - error_logger:error_msg("~p(~p): Waiting for process ~p to die ~p\n", + error_logger:error_msg("~w(~w): Waiting for process ~w to die ~tp\n", [?MODULE, ?LINE, Pid, File]), wait_for_processto_die(Ref, Pid, File) end. @@ -1218,7 +1223,7 @@ add_missing_mods(AppName, EbinMods, AppModNames) -> [missing_mod(ModName, AppName) || ModName <- MissingModNames]. missing_mod(ModName, AppName) -> - %% io:format("Missing: ~p -> ~p\n", [AppName, ModName]), + %% io:format("Missing: ~w -> ~w\n", [AppName, ModName]), #mod{name = ModName, app_name = AppName, incl_cond = undefined, @@ -1318,7 +1323,7 @@ read_config(OldSys, Filename) when is_list(Filename) -> {ok, Content} -> reltool_utils:throw_error("Illegal file content: ~p",[Content]); {error, Reason} -> - reltool_utils:throw_error("Illegal config file ~p: ~s", + reltool_utils:throw_error("Illegal config file ~tp: ~ts", [Filename,file:format_error(Reason)]) end; read_config(OldSys, {sys, KeyVals}) -> @@ -1336,7 +1341,7 @@ read_config(OldSys, {sys, KeyVals}) -> NewSys2; false -> reltool_utils:throw_error( - "Release ~p is mandatory (used as boot_rel)", + "Release ~tp is mandatory (used as boot_rel)", [NewSys2#sys.boot_rel]) end; read_config(_OldSys, BadConfig) -> @@ -1505,7 +1510,7 @@ decode(#app{} = App, [{Key, Val} | KeyVals]) -> active_dir = Dir, sorted_dirs = [Dir]}; false -> - reltool_utils:throw_error("Illegal lib dir for ~p: ~p", + reltool_utils:throw_error("Illegal lib dir for ~w: ~p", [App#app.name, Val]) end; SelectVsn when SelectVsn=:=vsn; SelectVsn=:=lib_dir -> @@ -1637,7 +1642,7 @@ patch_erts_version(RootDir, Apps, Status) -> end; false -> reltool_utils:throw_error( - "erts cannot be found in the root directory ~p", [RootDir]) + "erts cannot be found in the root directory ~tp", [RootDir]) end. libs_to_dirs(RootDir, LibDirs) -> @@ -1664,10 +1669,10 @@ libs_to_dirs(RootDir, LibDirs) -> lists:prefix("erts", F)], app_dirs2(AllLibDirs, [ErtsFiles]); [Duplicate | _] -> - reltool_utils:throw_error("Duplicate library: ~p",[Duplicate]) + reltool_utils:throw_error("Duplicate library: ~tp",[Duplicate]) end; {error, Reason} -> - reltool_utils:throw_error("Missing root library ~p: ~s", + reltool_utils:throw_error("Missing root library ~tp: ~ts", [RootDir,file:format_error(Reason)]) end. @@ -1680,8 +1685,7 @@ app_dirs2([Lib | Libs], Acc) -> EbinDir = filename:join([AppDir, "ebin"]), case filelib:is_dir(EbinDir, erl_prim_loader) of true -> - {Name, _Vsn} = - reltool_utils:split_app_name(Base), + Name = find_app_name(Base,EbinDir), case Name of erts -> false; _ -> {true, {Name, AppDir}} @@ -1693,23 +1697,80 @@ app_dirs2([Lib | Libs], Acc) -> Files2 = lists:zf(Filter, Files), app_dirs2(Libs, [Files2 | Acc]); {error, Reason} -> - reltool_utils:throw_error("Illegal library ~p: ~s", + reltool_utils:throw_error("Illegal library ~tp: ~ts", [Lib, file:format_error(Reason)]) end; app_dirs2([], Acc) -> lists:sort(lists:append(Acc)). +find_app_name(Base,EbinDir) -> + {ok,EbinFiles} = erl_prim_loader:list_dir(EbinDir), + AppFile = + case [F || F <- EbinFiles, filename:extension(F)=:=".app"] of + [AF] -> + AF; + _ -> + undefined + end, + find_app_name1(Base,AppFile). + +find_app_name1(Base,undefined) -> + {Name,_} = reltool_utils:split_app_name(Base), + Name; +find_app_name1(_Base,AppFile) -> + list_to_atom(filename:rootname(AppFile)). + +get_vsn_from_dir(AppName,Base) -> + Prefix = atom_to_list(AppName) ++ "-", + case lists:prefix(Prefix,Base) of + true -> + lists:nthtail(length(Prefix),Base); + false -> + "" + end. + + escripts_to_apps([Escript | Escripts], Apps, Status) -> {EscriptAppName, _Label} = split_escript_name(Escript), Ext = code:objfile_extension(), + + %% First find all .app files and associate the app name to the app + %% label - this is in order to now which application a module + %% belongs to in the next round. + AppFun = fun(FullName, _GetInfo, _GetBin, AppFiles) -> + Components = filename:split(FullName), + case Components of + [AppLabel, "ebin", File] -> + case filename:extension(File) of + ".app" -> + [{AppLabel,File}|AppFiles]; + _ -> + AppFiles + end; + _ -> + AppFiles + end + end, + AppFiles = + case reltool_utils:escript_foldl(AppFun, [], Escript) of + {ok, AF} -> + AF; + {error, Reason1} -> + reltool_utils:throw_error("Illegal escript ~tp: ~p", + [Escript,Reason1]) + end, + + %% Next, traverse all files... Fun = fun(FullName, _GetInfo, GetBin, {FileAcc, StatusAcc}) -> Components = filename:split(FullName), case Components of [AppLabel, "ebin", File] -> case filename:extension(File) of ".app" -> - {AppName, DefaultVsn} = - reltool_utils:split_app_name(AppLabel), + AppName = + list_to_atom(filename:rootname(File)), + DefaultVsn = + get_vsn_from_dir(AppName,AppLabel), AppFileName = filename:join([Escript, FullName]), {Info, StatusAcc2} = @@ -1722,8 +1783,9 @@ escripts_to_apps([Escript | Escripts], Apps, Status) -> {[{AppName, app, Dir, Info} | FileAcc], StatusAcc2}; E when E =:= Ext -> - {AppName, _} = - reltool_utils:split_app_name(AppLabel), + AppFile = + proplists:get_value(AppLabel,AppFiles), + AppName = find_app_name1(AppLabel,AppFile), Mod = init_mod(AppName, File, {File, GetBin()}, @@ -1760,6 +1822,7 @@ escripts_to_apps([Escript | Escripts], Apps, Status) -> {FileAcc, StatusAcc} end end, + case reltool_utils:escript_foldl(Fun, {[], Status}, Escript) of {ok, {Files, Status2}} -> EscriptApp = @@ -1774,8 +1837,9 @@ escripts_to_apps([Escript | Escripts], Apps, Status) -> Apps, Status2), escripts_to_apps(Escripts, Apps2, Status3); - {error, Reason} -> - reltool_utils:throw_error("Illegal escript ~p: ~p", [Escript,Reason]) + {error, Reason2} -> + reltool_utils:throw_error("Illegal escript ~tp: ~p", + [Escript,Reason2]) end; escripts_to_apps([], Apps, Status) -> {Apps, Status}. @@ -1837,7 +1901,7 @@ init_escript_app(AppName, EscriptAppName, Dir, Info, Mods, Apps, Status) -> case lists:keymember(AppName, #app.name, Apps) of true -> reltool_utils:throw_error( - "~p: Application name clash. Escript ~p contains application ~p.", + "~w: Application name clash. Escript ~tp contains application ~tp.", [AppName,Dir,AppName]); false -> {App2, Status} @@ -1922,7 +1986,7 @@ ensure_app_info(#app{is_escript = IsEscript, active_dir = Dir, info = Info}, %% Escript or application which is inlined in an escript {Info, Dir, Status}; ensure_app_info(#app{name = Name, sorted_dirs = []}, _Status) -> - reltool_utils:throw_error("~p: : Missing application directory.",[Name]); + reltool_utils:throw_error("~w: : Missing application directory.",[Name]); ensure_app_info(#app{name = Name, vsn = Vsn, use_selected_vsn = UseSelectedVsn, @@ -1934,7 +1998,7 @@ ensure_app_info(#app{name = Name, fun(Dir, StatusAcc) -> Base = get_base(Name, Dir), Ebin = filename:join([Dir, "ebin"]), - {_, DefaultVsn} = reltool_utils:split_app_name(Base), + DefaultVsn = get_vsn_from_dir(Name,Base), AppFile = filename:join([Ebin, atom_to_list(Name) ++ ".app"]), read_app_info(AppFile, AppFile, Name, DefaultVsn, StatusAcc) end, @@ -1947,8 +2011,8 @@ ensure_app_info(#app{name = Name, Status2; [BadVsn | _] -> reltool_utils:throw_error( - "~p: Application version clash. " - "Multiple directories contains version ~p.", + "~w: Application version clash. " + "Multiple directories contains version ~tp.", [Name,BadVsn]) end, FirstInfo = hd(AllInfo), @@ -1970,8 +2034,8 @@ ensure_app_info(#app{name = Name, {Info, VsnDir, Status3}; false -> reltool_utils:throw_error( - "~p: No application directory contains " - "selected version ~p", [Name,Vsn]) + "~w: No application directory contains " + "selected version ~tp", [Name,Vsn]) end end; true -> diff --git a/lib/reltool/src/reltool_sys_win.erl b/lib/reltool/src/reltool_sys_win.erl index 0c0b295db1..b5d54e6d3e 100644 --- a/lib/reltool/src/reltool_sys_win.erl +++ b/lib/reltool/src/reltool_sys_win.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2009-2012. All Rights Reserved. +%% Copyright Ericsson AB 2009-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -49,7 +49,6 @@ rel_book, lib_tree, status_bar, - popup_menu, source, whitelist, blacklist, @@ -136,6 +135,7 @@ init(Options) -> do_init(Options) catch error:Reason -> + io:format("~p: ~p~n",[Reason, erlang:get_stacktrace()]), exit({Reason, erlang:get_stacktrace()}) end. @@ -181,7 +181,7 @@ do_init([{safe_config, Safe}, {parent, Parent} | Options]) -> end. restart_server_safe_config(true,Parent,Reason) -> - io:format("~p(~p): <ERROR> ~p\n", [?MODULE, ?LINE, Reason]), + io:format("~w(~w): <ERROR> ~p\n", [?MODULE, ?LINE, Reason]), proc_lib:init_ack(Parent, {error,Reason}); restart_server_safe_config(false,Parent,Reason) -> wx:new(), @@ -198,7 +198,7 @@ restart_server_safe_config(false,Parent,Reason) -> ?wxID_OK -> do_init([{safe_config,true},{parent,Parent},?safe_config]); ?wxID_CANCEL -> - io:format("~p(~p): <ERROR> ~p\n", [?MODULE, ?LINE, Reason]), + io:format("~w(~w): <ERROR> ~p\n", [?MODULE, ?LINE, Reason]), proc_lib:init_ack(Parent,{error,Reason}) end. @@ -211,7 +211,7 @@ exit_dialog(Warnings) -> ?wxID_OK -> ok; ?wxID_CANCEL -> - io:format("~p(~p): <ERROR> ~s\n", [?MODULE, ?LINE, Details]), + io:format("~w(~w): <ERROR> ~ts\n", [?MODULE, ?LINE, Details]), exit(Details) end. @@ -249,7 +249,7 @@ loop(S) -> WWs2 = lists:delete(ObjRef, WWs), ?MODULE:loop(S#state{warning_wins = WWs2}); false -> - error_logger:format("~p~p got unexpected " + error_logger:format("~w~w got unexpected " "message:\n\t~p\n", [?MODULE, self(), Msg]), ?MODULE:loop(S) @@ -291,7 +291,7 @@ loop(S) -> S#state.app_wins), ?MODULE:loop(S#state{fgraph_wins = FWs, app_wins = AWs}); Msg -> - error_logger:format("~p~p got unexpected message:\n\t~p\n", + error_logger:format("~w~w got unexpected message:\n\t~p\n", [?MODULE, self(), Msg]), ?MODULE:loop(S) end. @@ -315,7 +315,7 @@ handle_child_exit({'EXIT', Pid, _Reason} = Exit, FWs, AWs) -> msg_warning({'EXIT', _Pid, shutdown}, Type) when Type =/= unknown -> ok; msg_warning(Exit, Type) -> - error_logger:format("~p~p got unexpected message (~p):\n\t~p\n", + error_logger:format("~w~w got unexpected message (~w):\n\t~p\n", [?MODULE, self(), Type, Exit]). create_window(S) -> @@ -403,8 +403,6 @@ create_menubar(Frame) -> wxEvtHandler:connect(Frame, command_menu_selected, [{userData, main_window}]), - wxEvtHandler:connect(File, menu_close), - wxEvtHandler:connect(Help, menu_close), MenuBar. create_app_page(#state{book = Book} = S) -> @@ -780,15 +778,12 @@ root_popup(S, Root, Tree, Item) -> wxMenu:appendSeparator(PopupMenu), wxMenu:append(PopupMenu, 1, "Edit"), Choices = [edit], - wxEvtHandler:connect(PopupMenu, command_menu_selected), - wxEvtHandler:connect(PopupMenu, menu_close), + Popup = #root_popup{dir = Root, choices = Choices, + tree = Tree, item = Item}, + wxEvtHandler:connect(PopupMenu, command_menu_selected, [{userData, {popup, Popup}}]), wxWindow:popupMenu(S#state.frame, PopupMenu), - Popup = #root_popup{dir = Root, - choices = Choices, - tree = Tree, - item = Item}, - S#state{popup_menu = Popup}. + S. lib_popup(S, Lib, Tree, Item) -> PopupMenu = wxMenu:new(), @@ -804,12 +799,10 @@ lib_popup(S, Lib, Tree, Item) -> wxMenu:append(PopupMenu, 3, "Delete"), [add, edit, delete] end, - wxEvtHandler:connect(PopupMenu, command_menu_selected), - wxEvtHandler:connect(PopupMenu, menu_close), - wxWindow:popupMenu(S#state.frame, PopupMenu), - Popup = #lib_popup{dir = Lib, choices = Choices, tree = Tree, item = Item}, - S#state{popup_menu = Popup}. + wxEvtHandler:connect(PopupMenu, command_menu_selected, [{userData, {popup, Popup}}]), + wxWindow:popupMenu(S#state.frame, PopupMenu), + S. escript_popup(S, File, Tree, Item) -> PopupMenu = wxMenu:new(), @@ -825,15 +818,11 @@ escript_popup(S, File, Tree, Item) -> wxMenu:append(PopupMenu, 3, "Delete"), [add, edit, delete] end, - wxEvtHandler:connect(PopupMenu, command_menu_selected), - wxEvtHandler:connect(PopupMenu, menu_close), + Popup = #escript_popup{file = File, choices = Choices, + tree = Tree, item = Item}, + wxEvtHandler:connect(PopupMenu, command_menu_selected, [{userData, {popup, Popup}}]), wxWindow:popupMenu(S#state.frame, PopupMenu), - - Popup = #escript_popup{file = File, - choices = Choices, - tree = Tree, - item = Item}, - S#state{popup_menu = Popup}. + S. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -903,11 +892,13 @@ handle_event(S, #wx{id = Id, obj= ObjRef, userData = UserData, event = Event} = wxMessageDialog:showModal(MD), wxMessageDialog:destroy(MD), S; - #wxMenu{type = menu_close} -> - S#state{popup_menu = undefined}; - #wxCommand{type = command_menu_selected = Type, cmdString = Str} - when S#state.popup_menu =/= undefined -> - handle_popup_event(S, Type, Id, ObjRef, UserData, Str); + #wxCommand{type = command_menu_selected = Type, cmdString = Str} -> + case UserData of + {popup, Popup} -> + handle_popup_event(S, Type, Id, ObjRef, Popup, Str); + true -> + S + end; #wxMouse{type = enter_window} -> %% The following is commented out because it raises the %% main system window on top of popup windows. @@ -1028,11 +1019,9 @@ warning_popup_position(#state{frame=MF,warning_list=WL},{WFW,WFH}) -> {X,Y}. handle_popup_event(S, _Type, 0, _ObjRef, _UserData, _Str) -> - S#state{popup_menu = undefined}; -handle_popup_event(#state{popup_menu = #root_popup{dir = OldDir, - choices = Choices}, - sys = Sys} = S, - _Type, Pos, _ObjRef, _UserData, _Str) -> + S; +handle_popup_event(#state{sys = Sys} = S, _Type, Pos, _ObjRef, + #root_popup{dir = OldDir, choices = Choices}, _Str) -> case lists:nth(Pos, Choices) of edit -> Style = ?wxFD_OPEN bor ?wxFD_FILE_MUST_EXIST, @@ -1042,18 +1031,16 @@ handle_popup_event(#state{popup_menu = #root_popup{dir = OldDir, Style) of {ok, NewDir} when NewDir =:= OldDir -> %% Same dir.Ignore. - S#state{popup_menu = undefined}; + S; {ok, NewDir} -> Sys2 = Sys#sys{root_dir = NewDir}, - do_set_sys(S#state{popup_menu = undefined, sys = Sys2}); + do_set_sys(S#state{sys = Sys2}); cancel -> - S#state{popup_menu = undefined} + S end end; -handle_popup_event(#state{popup_menu = #lib_popup{dir = OldDir, - choices = Choices}, - sys = Sys} = S, - _Type, Pos, _ObjRef, _UserData, _Str) -> +handle_popup_event(#state{sys = Sys} = S, _Type, Pos, _ObjRef, + #lib_popup{dir = OldDir, choices = Choices}, _Str) -> case lists:nth(Pos, Choices) of add -> {ok, Cwd} = file:get_cwd(), @@ -1063,15 +1050,14 @@ handle_popup_event(#state{popup_menu = #lib_popup{dir = OldDir, case lists:member(NewDir, Sys#sys.lib_dirs) of true -> %% Ignore duplicate. Keep old. - S#state{popup_menu = undefined}; + S; false -> LibDirs = Sys#sys.lib_dirs ++ [NewDir], Sys2 = Sys#sys{lib_dirs = LibDirs}, - do_set_sys(S#state{popup_menu = undefined, - sys = Sys2}) + do_set_sys(S#state{sys = Sys2}) end; cancel -> - S#state{popup_menu = undefined} + S end; edit -> Style = ?wxFD_OPEN bor ?wxFD_FILE_MUST_EXIST, @@ -1083,28 +1069,25 @@ handle_popup_event(#state{popup_menu = #lib_popup{dir = OldDir, case lists:member(NewDir, Sys#sys.lib_dirs) of true -> %% Ignore duplicate. Keep old. - S#state{popup_menu = undefined}; + S; false -> Pred = fun(E) -> E =/= OldDir end, {Before, [_| After]} = lists:splitwith(Pred, Sys#sys.lib_dirs), LibDirs2 = Before ++ [NewDir | After], Sys2 = Sys#sys{lib_dirs = LibDirs2}, - do_set_sys(S#state{popup_menu = undefined, - sys = Sys2}) + do_set_sys(S#state{sys = Sys2}) end; cancel -> - S#state{popup_menu = undefined} + S end; delete -> LibDirs = Sys#sys.lib_dirs -- [OldDir], Sys2 = Sys#sys{lib_dirs = LibDirs}, - do_set_sys(S#state{popup_menu = undefined, sys = Sys2}) + do_set_sys(S#state{sys = Sys2}) end; -handle_popup_event(#state{popup_menu = #escript_popup{file = OldFile, - choices = Choices}, - sys = Sys} = S, - _Type, Pos, _ObjRef, _UserData, _Str) -> +handle_popup_event(#state{sys = Sys} = S, _Type, Pos, _ObjRef, + #escript_popup{file = OldFile, choices = Choices}, _Str) -> case lists:nth(Pos, Choices) of add -> OldFile2 = @@ -1124,14 +1107,14 @@ handle_popup_event(#state{popup_menu = #escript_popup{file = OldFile, case lists:member(NewFile, Sys#sys.escripts) of true -> %% Ignore duplicate. Keep old. - S#state{popup_menu = undefined}; + S; false -> Escripts = Sys#sys.escripts ++ [NewFile], Sys2 = Sys#sys{escripts = Escripts}, - do_set_sys(S#state{popup_menu = undefined, sys = Sys2}) + do_set_sys(S#state{sys = Sys2}) end; cancel -> - S#state{popup_menu = undefined} + S end; edit -> Style = ?wxFD_OPEN bor ?wxFD_FILE_MUST_EXIST, @@ -1143,23 +1126,22 @@ handle_popup_event(#state{popup_menu = #escript_popup{file = OldFile, case lists:member(NewFile, Sys#sys.escripts) of true -> %% Ignore duplicate. Keep old. - S#state{popup_menu = undefined}; + S; false -> Pred = fun(E) -> E =/= OldFile end, {Before, [_| After]} = lists:splitwith(Pred, Sys#sys.escripts), Escripts2 = Before ++ [NewFile | After], Sys2 = Sys#sys{escripts = Escripts2}, - do_set_sys(S#state{popup_menu = undefined, - sys = Sys2}) + do_set_sys(S#state{sys = Sys2}) end; cancel -> - S#state{popup_menu = undefined} + S end; delete -> Escripts = Sys#sys.escripts -- [OldFile], Sys2 = Sys#sys{escripts = Escripts}, - do_set_sys(S#state{popup_menu = undefined, sys = Sys2}) + do_set_sys(S#state{sys = Sys2}) end. handle_system_event(#state{sys = Sys} = S, @@ -1179,7 +1161,7 @@ handle_system_event(#state{sys = Sys} = S, Sys2 = Sys#sys{incl_cond = AppCond}, do_set_sys(S#state{sys = Sys2}); handle_system_event(S, Event, ObjRef, UserData) -> - error_logger:format("~p~p got unexpected wx sys event to ~p " + error_logger:format("~w~w got unexpected wx sys event to ~p " "with user data: ~p\n\t ~p\n", [?MODULE, self(), ObjRef, UserData, Event]), S. @@ -1195,13 +1177,13 @@ handle_source_event(S, _UserData) -> case wxTreeCtrl:getItemData(ObjRef, Item) of #root_data{dir = _Dir} -> - %% io:format("Root dialog: ~p\n", [Dir]), + %% io:format("Root dialog: ~tp\n", [Dir]), S; #lib_data{dir = _Dir} -> - %% io:format("Lib dialog: ~p\n", [Dir]), + %% io:format("Lib dialog: ~tp\n", [Dir]), S; #escript_data{file = _File} -> - %% io:format("Escript dialog: ~p\n", [File]), + %% io:format("Escript dialog: ~tp\n", [File]), S; #app_data{name = Name} -> do_open_app(S, Name); @@ -1221,7 +1203,7 @@ handle_source_event(S, #escript_data{file = File} -> wx:batch(fun() -> escript_popup(S, File, Tree, Item) end); #app_data{name = Name} -> - io:format("App menu: ~p\n", [Name]), + io:format("App menu: ~tp\n", [Name]), S; undefined -> S @@ -1241,7 +1223,7 @@ handle_app_event(S, Items = reltool_utils:get_items(ListCtrl), handle_app_button(S, Items, Action); handle_app_event(S, Event, ObjRef, UserData) -> - error_logger:format("~p~p got unexpected wx app event to " + error_logger:format("~w~w got unexpected wx app event to " "~p with user data: ~p\n\t ~p\n", [?MODULE, self(), ObjRef, UserData, Event]), S. @@ -1285,7 +1267,7 @@ move_app(S, {_ItemNo, AppBase}, Action) -> blacklist_del -> undefined; _ -> - error_logger:format("~p~p got unexpected app " + error_logger:format("~w~w got unexpected app " "button event: ~p ~p\n", [?MODULE, self(), Action, AppBase]), OldApp#app.incl_cond diff --git a/lib/reltool/src/reltool_target.erl b/lib/reltool/src/reltool_target.erl index c39ed0ecd5..9cda5dabd3 100644 --- a/lib/reltool/src/reltool_target.erl +++ b/lib/reltool/src/reltool_target.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2009-2012. All Rights Reserved. +%% Copyright Ericsson AB 2009-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -296,7 +296,7 @@ do_gen_rel(#rel{name = RelName, vsn = RelVsn, rel_apps = RelApps}, {ErtsName, Erts#app.vsn}, [strip_rel_info(App, RelApps) || App <- MergedApps]}; false -> - reltool_utils:throw_error("Mandatory application ~p is " + reltool_utils:throw_error("Mandatory application ~w is " "not included", [ErtsName]) end. @@ -333,7 +333,9 @@ merge_apps(#rel{name = RelName, A#app.name =/= ?MISSING_APP_NAME, not lists:keymember(A#app.name, #app.name, MergedApps2)], MergedApps3 = do_merge_apps(RelName, Embedded, Apps, EmbAppType, MergedApps2), - sort_apps(lists:reverse(MergedApps3)). + RevMerged = lists:reverse(MergedApps3), + MergedSortedUsedAndIncs = sort_used_and_incl_apps(RevMerged,RevMerged), + sort_apps(MergedSortedUsedAndIncs). do_merge_apps(RelName, [#rel_app{name = Name} = RA | RelApps], Apps, RelAppType, Acc) -> case is_already_merged(Name, RelApps, Acc) of @@ -342,9 +344,11 @@ do_merge_apps(RelName, [#rel_app{name = Name} = RA | RelApps], Apps, RelAppType, false -> {value, App} = lists:keysearch(Name, #app.name, Apps), MergedApp = merge_app(RelName, RA, RelAppType, App), - MoreNames = (MergedApp#app.info)#app_info.applications, + ReqNames = (MergedApp#app.info)#app_info.applications, + IncNames = (MergedApp#app.info)#app_info.incl_apps, Acc2 = [MergedApp | Acc], - do_merge_apps(RelName, MoreNames ++ RelApps, Apps, RelAppType, Acc2) + do_merge_apps(RelName, ReqNames ++ IncNames ++ RelApps, + Apps, RelAppType, Acc2) end; do_merge_apps(RelName, [Name | RelApps], Apps, RelAppType, Acc) -> case is_already_merged(Name, RelApps, Acc) of @@ -379,8 +383,8 @@ merge_app(RelName, [] -> App#app{app_type = Type2, info = Info#app_info{incl_apps = InclApps}}; BadIncl -> - reltool_utils:throw_error("~p: These applications are " - "used by release ~s but are " + reltool_utils:throw_error("~w: These applications are " + "used by release ~ts but are " "missing as included_applications " "in the app file: ~p", [Name, RelName, BadIncl]) @@ -478,33 +482,62 @@ do_gen_script(#rel{name = RelName, vsn = RelVsn}, %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -load_app_mods(#app{mods = Mods} = App, Mand, PathFlag, Variables) -> +load_app_mods(#app{mods = Mods0} = App, Mand, PathFlag, Variables) -> Path = cr_path(App, PathFlag, Variables), - PartNames = - lists:sort([{packages:split(M),M} || - #mod{name = M, is_included=true} <- Mods, - not lists:member(M, Mand)]), - SplitMods = - lists:foldl( - fun({Parts,M}, [{Last, Acc}|Rest]) -> - [_|Tail] = lists:reverse(Parts), - case lists:reverse(Tail) of - Subs when Subs == Last -> - [{Last,[M|Acc]}|Rest]; - Subs -> - [{Subs, [M]}|[{Last,Acc}|Rest]] - end - end, - [{[], - []}], - PartNames), - lists:foldl( - fun({Subs,Ms}, Cmds) -> - [{path, [filename:join([Path | Subs])]}, - {primLoad, lists:sort(Ms)} | Cmds] - end, - [], - SplitMods). + Mods = [M || #mod{name = M, is_included=true} <- Mods0, + not lists:member(M, Mand)], + [{path, [filename:join([Path])]}, + {primLoad, lists:sort(Mods)}]. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% sort_used_and_incl_apps(Apps, OrderedApps) -> Apps +%% Apps = [#app{}] +%% OrderedApps = [#app{}] +%% +%% OTP-4121, OTP-9984 +%% (Tickets are written for systools, but needs to be implemented here +%% as well.) +%% Make sure that used and included applications are given in the same +%% order as in the release resource file (.rel). Otherwise load and +%% start instructions in the boot script, and consequently release +%% upgrade instructions in relup, may end up in the wrong order. + +sort_used_and_incl_apps([#app{info=Info} = App|Apps], OrderedApps) -> + Incls2 = + case Info#app_info.incl_apps of + Incls when length(Incls)>1 -> + sort_appl_list(Incls, OrderedApps); + Incls -> + Incls + end, + Uses2 = + case Info#app_info.applications of + Uses when length(Uses)>1 -> + sort_appl_list(Uses, OrderedApps); + Uses -> + Uses + end, + App2 = App#app{info=Info#app_info{incl_apps=Incls2, applications=Uses2}}, + [App2|sort_used_and_incl_apps(Apps, OrderedApps)]; +sort_used_and_incl_apps([], _OrderedApps) -> + []. + +sort_appl_list(List, Order) -> + IndexedList = find_pos(List, Order), + SortedIndexedList = lists:keysort(1, IndexedList), + lists:map(fun({_Index,Name}) -> Name end, SortedIndexedList). + +find_pos([Name|Incs], OrderedApps) -> + [find_pos(1, Name, OrderedApps)|find_pos(Incs, OrderedApps)]; +find_pos([], _OrderedApps) -> + []. + +find_pos(N, Name, [#app{name=Name}|_OrderedApps]) -> + {N, Name}; +find_pos(N, Name, [_OtherAppl|OrderedApps]) -> + find_pos(N+1, Name, OrderedApps). + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Function: sort_apps(Apps) -> {ok, Apps'} | throw({error, Error}) @@ -832,7 +865,7 @@ strip_sys_files(Relocatable, SysFiles, Apps, ExclRegexps) -> case File of "erts" -> reltool_utils:throw_error("This system is not installed. " - "The directory ~s is missing.", + "The directory ~ts is missing.", [Erts#app.label]); _ when File =:= Erts#app.label -> replace_dyn_erl(Relocatable, Spec); @@ -954,7 +987,7 @@ check_sys(Mandatory, SysFiles) -> do_check_sys(Prefix, Specs) -> case lookup_spec(Prefix, Specs) of [] -> - reltool_utils:throw_error("Mandatory system directory ~s " + reltool_utils:throw_error("Mandatory system directory ~ts " "is not included", [Prefix]); _ -> @@ -975,8 +1008,8 @@ lookup_spec(Prefix, Specs) -> safe_lookup_spec(Prefix, Specs) -> case lookup_spec(Prefix, Specs) of [] -> - %% io:format("lookup fail ~s:\n\t~p\n", [Prefix, Specs]), - reltool_utils:throw_error("Mandatory system file ~s is " + %% io:format("lookup fail ~ts:\n\t~p\n", [Prefix, Specs]), + reltool_utils:throw_error("Mandatory system file ~ts is " "not included", [Prefix]); Match -> Match @@ -1020,7 +1053,7 @@ spec_lib_files(#sys{root_dir = RootDir, check_apps([Mandatory | Names], Apps) -> case lists:keymember(Mandatory, #app.name, Apps) of false -> - reltool_utils:throw_error("Mandatory application ~p is " + reltool_utils:throw_error("Mandatory application ~w is " "not included in ~p", [Mandatory, Apps]); true -> @@ -1111,13 +1144,13 @@ spec_dir(Dir) -> Base, [spec_dir(filename:join([Dir, F])) || F <- Files]}; error -> - reltool_utils:throw_error("list dir ~s failed", [Dir]) + reltool_utils:throw_error("list dir ~ts failed", [Dir]) end; {ok, #file_info{type = regular}} -> %% Plain file {copy_file, Base}; _ -> - reltool_utils:throw_error("read file info ~s failed", [Dir]) + reltool_utils:throw_error("read file info ~ts failed", [Dir]) end. spec_mod(Mod, DebugInfo) -> @@ -1251,7 +1284,7 @@ do_eval_spec({archive, Archive, Options, Files}, {ok, _} -> ok; {error, Reason} -> - reltool_utils:throw_error("create archive ~s failed: ~p", + reltool_utils:throw_error("create archive ~ts failed: ~p", [ArchiveFile, Reason]) end; do_eval_spec({copy_file, File}, _OrigSourceDir, SourceDir, TargetDir) -> @@ -1420,12 +1453,10 @@ do_install(RelName, TargetDir) -> BinDir = filename:join([TargetDir2, "bin"]), case os:type() of {win32, _} -> - NativeRootDir = filename:nativename(TargetDir2), - %% NativeBinDir = - %% filename:nativename(filename:join([BinDir, "win32"])), - NativeBinDir = filename:nativename(BinDir), + NativeRootDir = nativename(TargetDir2), + NativeErtsBinDir = nativename(ErtsBinDir), IniData = ["[erlang]\r\n", - "Bindir=", NativeBinDir, "\r\n", + "Bindir=", NativeErtsBinDir, "\r\n", "Progname=erl\r\n", "Rootdir=", NativeRootDir, "\r\n"], IniFile = filename:join([BinDir, "erl.ini"]), @@ -1442,9 +1473,18 @@ do_install(RelName, TargetDir) -> ok = release_handler:create_RELEASES(TargetDir2, RelFile), ok; _ -> - reltool_utils:throw_error("~s: Illegal data file syntax", [DataFile]) + reltool_utils:throw_error("~ts: Illegal data file syntax",[DataFile]) end. +nativename(Dir) -> + escape_backslash(filename:nativename(Dir)). +escape_backslash([$\\|T]) -> + [$\\,$\\|escape_backslash(T)]; +escape_backslash([H|T]) -> + [H|escape_backslash(T)]; +escape_backslash([]) -> + []. + subst_src_scripts(Scripts, SrcDir, DestDir, Vars, Opts) -> Fun = fun(Script) -> subst_src_script(Script, SrcDir, DestDir, Vars, Opts) diff --git a/lib/reltool/src/reltool_utils.erl b/lib/reltool/src/reltool_utils.erl index 6149d6ef06..edccb889b1 100644 --- a/lib/reltool/src/reltool_utils.erl +++ b/lib/reltool/src/reltool_utils.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2009-2012. All Rights Reserved. +%% Copyright Ericsson AB 2009-2013. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -106,7 +106,7 @@ normalize_dir([], Path) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% prim_consult(Bin) when is_binary(Bin) -> - case erl_scan:string(binary_to_list(Bin)) of + case erl_scan:string(unicode:characters_to_list(Bin,encoding(Bin))) of {ok, Tokens, _EndLine} -> prim_parse(Tokens, []); {error, {_ErrorLine, Module, Reason}, _EndLine} -> @@ -120,6 +120,14 @@ prim_consult(FullName) when is_list(FullName) -> {error, file:format_error(enoent)} end. +encoding(Bin) when is_binary(Bin) -> + case epp:read_encoding_from_binary(Bin) of + none -> + epp:default_encoding(); + E -> + E + end. + prim_parse(Tokens, Acc) -> case lists:splitwith(fun(T) -> element(1,T) =/= dot end, Tokens) of {[], []} -> @@ -423,7 +431,7 @@ scroll_size(ObjRef) -> safe_keysearch(Key, Pos, List, Mod, Line) -> case lists:keysearch(Key, Pos, List) of false -> - io:format("~p(~p): lists:keysearch(~p, ~p, ~p) -> false\n", + io:format("~w(~w): lists:keysearch(~p, ~w, ~p) -> false\n", [Mod, Line, Key, Pos, List]), erlang:error({Mod, Line, lists, keysearch, [Key, Pos, List]}); {value, Val} -> @@ -455,7 +463,7 @@ create_dir(Dir) -> ok; {error, Reason} -> Text = file:format_error(Reason), - throw_error("create dir ~s: ~s", [Dir, Text]) + throw_error("create dir ~ts: ~ts", [Dir, Text]) end. list_dir(Dir) -> @@ -464,7 +472,7 @@ list_dir(Dir) -> Files; error -> Text = file:format_error(enoent), - throw_error("list dir ~s: ~s", [Dir, Text]) + throw_error("list dir ~ts: ~ts", [Dir, Text]) end. read_file_info(File) -> @@ -473,7 +481,7 @@ read_file_info(File) -> Info; {error, Reason} -> Text = file:format_error(Reason), - throw_error("read file info ~s: ~s", [File, Text]) + throw_error("read file info ~ts: ~ts", [File, Text]) end. write_file_info(File, Info) -> @@ -482,7 +490,7 @@ write_file_info(File, Info) -> ok; {error, Reason} -> Text = file:format_error(Reason), - throw_error("write file info ~s: ~s", [File, Text]) + throw_error("write file info ~ts: ~ts", [File, Text]) end. read_file(File) -> @@ -491,7 +499,7 @@ read_file(File) -> Bin; {error, Reason} -> Text = file:format_error(Reason), - throw_error("read file ~s: ~s", [File, Text]) + throw_error("read file ~ts: ~ts", [File, Text]) end. write_file(File, IoList) -> @@ -500,7 +508,7 @@ write_file(File, IoList) -> ok; {error, Reason} -> Text = file:format_error(Reason), - throw_error("write file ~s: ~s", [File, Text]) + throw_error("write file ~ts: ~ts", [File, Text]) end. recursive_delete(Dir) -> @@ -516,7 +524,7 @@ recursive_delete(Dir) -> ok; {error, Reason} -> Text = file:format_error(Reason), - throw_error("delete file ~s: ~s\n", [Dir, Text]) + throw_error("delete file ~ts: ~ts\n", [Dir, Text]) end; false -> delete(Dir, regular) @@ -530,7 +538,7 @@ delete(File, Type) -> ok; {error, Reason} -> Text = file:format_error(Reason), - throw_error("delete file ~s: ~s\n", [File, Text]) + throw_error("delete file ~ts: ~ts\n", [File, Text]) end. do_delete(File, regular) -> @@ -569,11 +577,11 @@ copy_file(From, To) -> ok; {error, Reason} -> Text = file:format_error(Reason), - throw_error("copy file ~s -> ~s: ~s\n", [From, To, Text]) + throw_error("copy file ~ts -> ~ts: ~ts\n", [From, To, Text]) end; error -> Text = file:format_error(enoent), - throw_error("copy file ~s -> ~s: ~s\n", [From, To, Text]) + throw_error("copy file ~ts -> ~ts: ~ts\n", [From, To, Text]) end. throw_error(Format, Args) -> @@ -586,13 +594,10 @@ decode_regexps(Key, {add, Regexps}, Old) when is_list(Regexps) -> decode_regexps(_Key, {del, Regexps}, Old) when is_list(Regexps) -> [Re || Re <- Old, not lists:member(Re#regexp.source, Regexps)]; decode_regexps(Key, Regexps, _Old) when is_list(Regexps) -> - do_decode_regexps(Key, Regexps, []); -decode_regexps(Key, Regexps, _Old) when is_list(Regexps) -> - Text = lists:flatten(io_lib:format("~p", [{Key, Regexps}])), - throw({error, "Illegal option: " ++ Text}). + do_decode_regexps(Key, Regexps, []). do_decode_regexps(Key, [Regexp | Regexps], Acc) -> - case catch re:compile(Regexp, []) of + case catch re:compile(Regexp, [unicode]) of {ok, MP} -> do_decode_regexps(Key, Regexps, |