diff options
Diffstat (limited to 'lib/tools')
-rw-r--r-- | lib/tools/c_src/Makefile.in | 10 | ||||
-rw-r--r-- | lib/tools/src/Makefile | 4 | ||||
-rw-r--r-- | lib/tools/src/cover.erl | 86 | ||||
-rw-r--r-- | lib/tools/src/lcnt.erl | 3 | ||||
-rw-r--r-- | lib/tools/src/xref_reader.erl | 9 | ||||
-rw-r--r-- | lib/tools/test/cover_SUITE.erl | 104 | ||||
-rw-r--r-- | lib/tools/test/xref_SUITE.erl | 65 |
7 files changed, 171 insertions, 110 deletions
diff --git a/lib/tools/c_src/Makefile.in b/lib/tools/c_src/Makefile.in index 0382d3228d..aea5686ae9 100644 --- a/lib/tools/c_src/Makefile.in +++ b/lib/tools/c_src/Makefile.in @@ -17,6 +17,7 @@ # %CopyrightEnd% # +include $(ERL_TOP)/make/output.mk include $(ERL_TOP)/make/target.mk include $(ERL_TOP)/erts/include/internal/$(TARGET)/ethread.mk @@ -150,7 +151,7 @@ _create_dirs := $(shell mkdir -p $(CREATE_DIRS)) all: $(PROGS) $(DRIVERS) $(ERTS_LIB): - cd $(ERL_TOP)/erts/lib_src && $(MAKE) $(TYPE) + $(make_verbose)cd $(ERL_TOP)/erts/lib_src && $(MAKE) $(TYPE) docs: @@ -167,7 +168,7 @@ clean: # $(EMEM_OBJ_DIR)/%.o: %.c - $(CC) $(EMEM_CFLAGS) -o $@ -c $< + $(V_CC) $(EMEM_CFLAGS) -o $@ -c $< # # Driver targets @@ -178,7 +179,7 @@ $(EMEM_OBJ_DIR)/%.o: %.c # $(BIN_DIR)/emem$(TYPEMARKER)@EXEEXT@: $(EMEM_OBJS) $(ERTS_LIB) - $(PRE_LD) $(LD) $(EMEM_LDFLAGS) -o $@ $(EMEM_OBJS) $(EMEM_LIBS) + $(ld_verbose)$(PRE_LD) $(LD) $(EMEM_LDFLAGS) -o $@ $(EMEM_OBJS) $(EMEM_LIBS) # # Release targets @@ -221,7 +222,8 @@ SED_DEPEND=sed '$(SED_REPL_OBJ_DIR);$(SED_REPL_TT_DIR);$(SED_REPL_TARGET);$(SED_ DEPEND_MK=depend.mk dep depend: - @echo "Generating dependency file $(DEPEND_MK)..." + [ $(v_p) == 0 ] && echo " GEN "$(DEPEND_MK) + $(V_colon)@echo "Generating dependency file $(DEPEND_MK)..." @echo "# Generated dependency rules." > $(DEPEND_MK); @echo "# Do *not* edit this file; instead, run 'make depend'." \ >> $(DEPEND_MK); diff --git a/lib/tools/src/Makefile b/lib/tools/src/Makefile index abe1389771..bdd0cdce25 100644 --- a/lib/tools/src/Makefile +++ b/lib/tools/src/Makefile @@ -94,10 +94,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);' $< > $@ # ---------------------------------------------------- # Release Target diff --git a/lib/tools/src/cover.erl b/lib/tools/src/cover.erl index 10f14b0a49..680c1781ca 100644 --- a/lib/tools/src/cover.erl +++ b/lib/tools/src/cover.erl @@ -705,7 +705,9 @@ main_process_loop(State) -> remote_collect('_',Nodes,true), reply(From, ok), Nodes1 = State#main_state.nodes--Nodes, - main_process_loop(State#main_state{nodes=Nodes1}); + LostNodes1 = State#main_state.lost_nodes--Nodes, + main_process_loop(State#main_state{nodes=Nodes1, + lost_nodes=LostNodes1}); {From, {flush,Nodes}} -> remote_collect('_',Nodes,false), @@ -792,8 +794,15 @@ main_process_loop(State) -> {'DOWN', _MRef, process, {?SERVER,Node}, _Info} -> %% A remote cover_server is down, mark as lost - Nodes = State#main_state.nodes--[Node], - Lost = [Node|State#main_state.lost_nodes], + {Nodes,Lost} = + case lists:member(Node,State#main_state.nodes) of + true -> + N = State#main_state.nodes--[Node], + L = [Node|State#main_state.lost_nodes], + {N,L}; + false -> % node stopped + {State#main_state.nodes,State#main_state.lost_nodes} + end, main_process_loop(State#main_state{nodes=Nodes,lost_nodes=Lost}); {nodeup,Node} -> @@ -1510,12 +1519,6 @@ aux_var(Vars, N) -> %% This way we will be able to exclude functions defined in include files. munge({function,0,module_info,_Arity,_Clauses},_Vars,_MainFile,_Switch) -> ignore; % module_info will be added again when the forms are recompiled -munge(Form={function,_,'MNEMOSYNE QUERY',_,_},Vars,_MainFile,Switch) -> - {Form,Vars,Switch}; % No bumps in Mnemosyne code. -munge(Form={function,_,'MNEMOSYNE RULE',_,_},Vars,_MainFile,Switch) -> - {Form,Vars,Switch}; -munge(Form={function,_,'MNEMOSYNE RECFUNDEF',_,_},Vars,_MainFile,Switch) -> - {Form,Vars,Switch}; munge({function,Line,Function,Arity,Clauses},Vars,_MainFile,on) -> Vars2 = Vars#vars{function=Function, arity=Arity, @@ -2087,30 +2090,40 @@ do_analyse_to_file(Module, OutFile, ErlFile, HTML) -> case file:open(OutFile, [write]) of {ok, OutFd} -> if HTML -> - io:format(OutFd, - "<html>\n" - "<head><title>~s</title></head>" - "<body bgcolor=white text=black>\n" - "<pre>\n", - [OutFile]); + Encoding = encoding(ErlFile), + Header = + ["<!DOCTYPE HTML PUBLIC " + "\"-//W3C//DTD HTML 3.2 Final//EN\">\n" + "<html>\n" + "<head>\n" + "<meta http-equiv=\"Content-Type\"" + " content=\"text/html; charset=", + Encoding,"\"/>\n" + "<title>",OutFile,"</title>\n" + "</head>" + "<body style='background-color: white;" + " color: black'>\n" + "<pre>\n"], + file:write(OutFd,Header); true -> ok end, %% Write some initial information to the output file {{Y,Mo,D},{H,Mi,S}} = calendar:local_time(), - io:format(OutFd, "File generated from ~s by COVER " - "~p-~s-~s at ~s:~s:~s~n", - [ErlFile, - Y, - string:right(integer_to_list(Mo), 2, $0), - string:right(integer_to_list(D), 2, $0), - string:right(integer_to_list(H), 2, $0), - string:right(integer_to_list(Mi), 2, $0), - string:right(integer_to_list(S), 2, $0)]), - io:format(OutFd, "~n" - "**************************************" - "**************************************" - "~n~n", []), + Timestamp = + io_lib:format("~p-~s-~s at ~s:~s:~s", + [Y, + string:right(integer_to_list(Mo), 2, $0), + string:right(integer_to_list(D), 2, $0), + string:right(integer_to_list(H), 2, $0), + string:right(integer_to_list(Mi), 2, $0), + string:right(integer_to_list(S), 2, $0)]), + file:write(OutFd, + ["File generated from ",ErlFile," by COVER ", + Timestamp,"\n\n" + "**************************************" + "**************************************" + "\n\n"]), print_lines(Module, InFd, OutFd, 1, HTML), @@ -2405,3 +2418,20 @@ pmap(Fun, [], [], Limit, Cnt, Acc) -> {'DOWN', _Ref, process, X, _} when is_pid(X) -> pmap(Fun, [], [], Limit, Cnt - 1, Acc) end. + +%%%----------------------------------------------------------------- +%%% Read encoding from source file +encoding(File) -> + Encoding = + case epp:read_encoding(File) of + none -> + epp:default_encoding(); + E -> + E + end, + html_encoding(Encoding). + +html_encoding(latin1) -> + "iso-8859-1"; +html_encoding(utf8) -> + "utf-8". diff --git a/lib/tools/src/lcnt.erl b/lib/tools/src/lcnt.erl index 989a661b75..70d62307c8 100644 --- a/lib/tools/src/lcnt.erl +++ b/lib/tools/src/lcnt.erl @@ -1,7 +1,8 @@ +%% -*- coding: utf-8 -*- %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010. All Rights Reserved. +%% Copyright Ericsson AB 2010-2012. 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 diff --git a/lib/tools/src/xref_reader.erl b/lib/tools/src/xref_reader.erl index 92f0c45c7b..2fcc2c503c 100644 --- a/lib/tools/src/xref_reader.erl +++ b/lib/tools/src/xref_reader.erl @@ -80,12 +80,6 @@ form({attribute, Line, xref, Calls}, S) -> % experimental attr(Calls, Line, M, Fun, L, X, B, S); form({attribute, _Line, _Attr, _Val}, S) -> S; -form({function, 0, 'MNEMOSYNE RULE', 1, _Clauses}, S) -> - S; -form({function, 0, 'MNEMOSYNE QUERY', 2, _Clauses}, S) -> - S; -form({function, 0, 'MNEMOSYNE RECFUNDEF', 1, _Clauses}, S) -> - S; form({function, 0, module_info, 0, _Clauses}, S) -> S; form({function, 0, module_info, 1, _Clauses}, S) -> @@ -331,9 +325,6 @@ handle_call(Locality, Module, Name, Arity, Line, S) -> handle_call(Locality, To, Line, S, false) end. -handle_call(_Locality, {_, 'MNEMOSYNE RULE',1}, _Line, S, _) -> S; -handle_call(_Locality, {_, 'MNEMOSYNE QUERY', 2}, _Line, S, _) -> S; -handle_call(_Locality, {_, 'MNEMOSYNE RECFUNDEF',1}, _Line, S, _) -> S; handle_call(Locality, To0, Line, S, IsUnres) -> From = S#xrefr.function, To = adjust_arity(S, To0), diff --git a/lib/tools/test/cover_SUITE.erl b/lib/tools/test/cover_SUITE.erl index 3bf1b44af8..57260a3869 100644 --- a/lib/tools/test/cover_SUITE.erl +++ b/lib/tools/test/cover_SUITE.erl @@ -23,7 +23,9 @@ init_per_group/2,end_per_group/2]). -export([start/1, compile/1, analyse/1, misc/1, stop/1, - distribution/1, reconnect/1, die_and_reconnect/1, export_import/1, + distribution/1, reconnect/1, die_and_reconnect/1, + dont_reconnect_after_stop/1, stop_node_after_disconnect/1, + export_import/1, otp_5031/1, eif/1, otp_5305/1, otp_5418/1, otp_6115/1, otp_7095/1, otp_8188/1, otp_8270/1, otp_8273/1, otp_8340/1]). @@ -47,6 +49,7 @@ all() -> undefined -> [start, compile, analyse, misc, stop, distribution, reconnect, die_and_reconnect, + dont_reconnect_after_stop, stop_node_after_disconnect, export_import, otp_5031, eif, otp_5305, otp_5418, otp_6115, otp_7095, otp_8188, otp_8270, otp_8273, otp_8340]; @@ -86,8 +89,11 @@ init_per_testcase(TC, Config) when TC =:= misc; init_per_testcase(_TestCase, Config) -> Config. -end_per_testcase(_TestCase, _Config) -> - %cover:stop(), +end_per_testcase(TestCase, _Config) -> + case lists:member(TestCase,[start,compile,analyse,misc]) of + true -> ok; + false -> cover:stop() + end, ok. start(suite) -> []; @@ -447,8 +453,8 @@ reconnect(Config) -> %% Disconnect and check that node is removed from main cover node net_kernel:disconnect(N1), + timer:sleep(500), % allow some to detect disconnect and for f:f2() call [] = cover:which_nodes(), - timer:sleep(500), % allow some time for the f:f2() call %% Do some add one module (b) and remove one module (a) code:purge(a), @@ -520,6 +526,94 @@ die_and_reconnect(Config) -> ?t:stop_node(N1), ok. +%% Test that a stopped node is not marked as lost, i.e. that it is not +%% reconnected if it is restarted (OTP-10638) +dont_reconnect_after_stop(Config) -> + DataDir = ?config(data_dir, Config), + ok = file:set_cwd(DataDir), + + {ok,f} = compile:file(f), + + NodeName = cover_SUITE_dont_reconnect_after_stop, + {ok,N1} = ?t:start_node(NodeName,peer, + [{args," -pa " ++ DataDir},{start_cover,false}]), + {ok,f} = cover:compile(f), + {ok,[N1]} = cover:start(nodes()), + + %% A call to check later + rpc:call(N1,f,f1,[]), + + %% Stop cover on the node, then terminate the node + cover:stop(N1), + rpc:call(N1,erlang,halt,[]), + [] = cover:which_nodes(), + + check_f_calls(1,0), + + %% Restart the node and check that cover does not reconnect + {ok,N1} = ?t:start_node(NodeName,peer, + [{args," -pa " ++ DataDir},{start_cover,false}]), + timer:sleep(300), + [] = cover:which_nodes(), + Beam = rpc:call(N1,code,which,[f]), + false = (Beam==cover_compiled), + + %% One more call... + rpc:call(N1,f,f1,[]), + cover:flush(N1), + + %% Ensure that the last call is not counted + check_f_calls(1,0), + + cover:stop(), + ?t:stop_node(N1), + ok. + +%% Test that a node which is stopped while it is marked as lost is not +%% reconnected if it is restarted (OTP-10638) +stop_node_after_disconnect(Config) -> + DataDir = ?config(data_dir, Config), + ok = file:set_cwd(DataDir), + + {ok,f} = compile:file(f), + + NodeName = cover_SUITE_stop_node_after_disconnect, + {ok,N1} = ?t:start_node(NodeName,peer, + [{args," -pa " ++ DataDir},{start_cover,false}]), + {ok,f} = cover:compile(f), + {ok,[N1]} = cover:start(nodes()), + + %% A call to check later + rpc:call(N1,f,f1,[]), + + %% Flush the node, then terminate the node to make it marked as lost + cover:flush(N1), + rpc:call(N1,erlang,halt,[]), + + check_f_calls(1,0), + + %% Stop cover on node + cover:stop(N1), + + %% Restart the node and check that cover does not reconnect + {ok,N1} = ?t:start_node(NodeName,peer, + [{args," -pa " ++ DataDir},{start_cover,false}]), + timer:sleep(300), + [] = cover:which_nodes(), + Beam = rpc:call(N1,code,which,[f]), + false = (Beam==cover_compiled), + + %% One more call... + rpc:call(N1,f,f1,[]), + cover:flush(N1), + + %% Ensure that the last call is not counted + check_f_calls(1,0), + + cover:stop(), + ?t:stop_node(N1), + ok. + export_import(suite) -> []; export_import(Config) when is_list(Config) -> ?line DataDir = ?config(data_dir, Config), @@ -908,7 +1002,7 @@ otp_8270(Config) when is_list(Config) -> ok. otp_8273(doc) -> - ["OTP-8270. Bug."]; + ["OTP-8273. Bug."]; otp_8273(suite) -> []; otp_8273(Config) when is_list(Config) -> Test = <<"-module(t). diff --git a/lib/tools/test/xref_SUITE.erl b/lib/tools/test/xref_SUITE.erl index fd3e111d8d..dc06678b8e 100644 --- a/lib/tools/test/xref_SUITE.erl +++ b/lib/tools/test/xref_SUITE.erl @@ -1,3 +1,4 @@ +%% -*- coding: utf-8 -*- %% %% %CopyrightBegin% %% @@ -46,7 +47,7 @@ -export([ add/1, default/1, info/1, lib/1, read/1, read2/1, remove/1, replace/1, update/1, deprecated/1, trycatch/1, - abstract_modules/1, fun_mfa/1, fun_mfa_r14/1, + fun_mfa/1, fun_mfa_r14/1, fun_mfa_vars/1, qlc/1]). -export([ @@ -82,7 +83,7 @@ groups() -> modules]}, {files, [], [add, default, info, lib, read, read2, remove, replace, - update, deprecated, trycatch, abstract_modules, fun_mfa, + update, deprecated, trycatch, fun_mfa, fun_mfa_r14, fun_mfa_vars, qlc]}, {analyses, [], [analyze, basic, md, q, variables, unused_locals]}, @@ -1668,64 +1669,6 @@ trycatch(Conf) when is_list(Conf) -> ok. -abstract_modules(suite) -> []; -abstract_modules(doc) -> ["OTP-5520: Abstract (parameterized) modules."]; -abstract_modules(Conf) when is_list(Conf) -> - Dir = ?copydir, - File = fname(Dir, "absmod.erl"), - MFile = fname(Dir, "absmod"), - Beam = fname(Dir, "absmod.beam"), - Test = <<"-module(param, [A, B]). - - -export([args/1]). - - args(C) -> - X = local(C), - Y = THIS:new(), % undef - Z = new(A, B), - {X, Y, Z}. - - local(C) -> - module_info(C). - ">>, - - ?line ok = file:write_file(File, Test), - - %% The compiler will no longer allow us to have a mismatch between - %% the module name and the output file, so we must use a trick. - ?line {ok, param, BeamCode} = compile:file(File, [binary,debug_info]), - ?line ok = file:write_file(Beam, BeamCode), - - ?line {ok, _} = xref:start(s), - ?line {ok, param} = xref:add_module(s, MFile, {warnings,false}), - A = param, - ?line {ok, [{{{A,args,1},{'$M_EXPR',new,0}},[7]}, - {{{A,args,1},{A,local,1}},[6]}, - {{{A,args,1},{A,new,2}},[8]}, - {{{A,local,1},{A,module_info,1}},[12]}, - {{{param,new,2},{param,instance,2}},[0]}]} = - xref:q(s, "(Lin) E"), - ?line {ok,[{param,args,1}, - {param,instance,2}, - {param,local,1}, - {param,module_info,1}, - {param,new,2}]} = xref:q(s, "F"), - - ?line ok = check_state(s), - ?line xref:stop(s), - - ?line {ok, _} = xref:start(s, {xref_mode, modules}), - ?line {ok, param} = xref:add_module(s, MFile), - ?line {ok,[{param,args,1}, - {param,instance,2}, - {param,new,2}]} = xref:q(s, "X"), - ?line ok = check_state(s), - ?line xref:stop(s), - - ?line ok = file:delete(File), - ?line ok = file:delete(Beam), - ok. - fun_mfa(suite) -> []; fun_mfa(doc) -> ["OTP-5653: fun M:F/A."]; fun_mfa(Conf) when is_list(Conf) -> @@ -2521,7 +2464,7 @@ otp_10192(doc) -> otp_10192(Conf) when is_list(Conf) -> PrivDir = ?privdir, {ok, _Pid} = xref:start(s), - Dir = filename:join(PrivDir, "�"), + Dir = filename:join(PrivDir, "ä"), ok = file:make_dir(Dir), {ok, []} = xref:add_directory(s, Dir), xref:stop(s), |