diff options
Diffstat (limited to 'lib/tools')
-rw-r--r-- | lib/tools/c_src/Makefile.in | 13 | ||||
-rw-r--r-- | lib/tools/doc/src/eprof.xml | 4 | ||||
-rw-r--r-- | lib/tools/doc/src/make.dep | 33 | ||||
-rw-r--r-- | lib/tools/doc/src/notes.xml | 79 | ||||
-rw-r--r-- | lib/tools/emacs/erlang-flymake.el | 3 | ||||
-rw-r--r-- | lib/tools/src/cover.erl | 4 | ||||
-rw-r--r-- | lib/tools/src/fprof.erl | 14 | ||||
-rw-r--r-- | lib/tools/src/xref_compiler.erl | 9 | ||||
-rw-r--r-- | lib/tools/src/xref_reader.erl | 25 | ||||
-rw-r--r-- | lib/tools/test/cover_SUITE.erl | 57 | ||||
-rw-r--r-- | lib/tools/test/cover_SUITE_data/otp_6115/f1.erl | 11 | ||||
-rw-r--r-- | lib/tools/test/eprof_SUITE.erl | 10 | ||||
-rw-r--r-- | lib/tools/test/eprof_SUITE_data/ed.script | 2 | ||||
-rw-r--r-- | lib/tools/test/eprof_SUITE_data/eed.erl | 91 | ||||
-rw-r--r-- | lib/tools/test/lcnt_SUITE.erl | 3 | ||||
-rw-r--r-- | lib/tools/test/xref_SUITE.erl | 87 | ||||
-rw-r--r-- | lib/tools/test/xref_SUITE_data/fun_mfa_r14.beam | bin | 0 -> 1116 bytes | |||
-rw-r--r-- | lib/tools/test/xref_SUITE_data/fun_mfa_r14.erl | 18 | ||||
-rw-r--r-- | lib/tools/vsn.mk | 2 |
19 files changed, 321 insertions, 144 deletions
diff --git a/lib/tools/c_src/Makefile.in b/lib/tools/c_src/Makefile.in index 65a7f5f424..604332a91e 100644 --- a/lib/tools/c_src/Makefile.in +++ b/lib/tools/c_src/Makefile.in @@ -20,7 +20,7 @@ include $(ERL_TOP)/make/target.mk include $(ERL_TOP)/erts/include/internal/$(TARGET)/ethread.mk USING_MINGW=@MIXED_CYGWIN_MINGW@ -USING_VC=@MIXED_CYGWIN_VC@ +USING_VC=@MIXED_VC@ CC=@CC@ LD=@LD@ @@ -142,7 +142,9 @@ EMEM_OBJS = $(addprefix $(EMEM_OBJ_DIR)/,$(notdir $(EMEM_SRCS:.c=.o))) # Misc targets # -all: $(CREATE_DIRS) erts_lib $(PROGS) $(DRIVERS) +_create_dirs := $(shell mkdir -p $(CREATE_DIRS)) + +all: erts_lib $(PROGS) $(DRIVERS) erts_lib: cd $(ERL_TOP)/erts/lib_src && $(MAKE) $(TYPE) @@ -158,13 +160,6 @@ clean: .PHONY: all erts_lib docs clean # -# Make dir targets -# - -$(CREATE_DIRS): - $(MKDIR) -p $@ - -# # Object targets # diff --git a/lib/tools/doc/src/eprof.xml b/lib/tools/doc/src/eprof.xml index 6d68c90768..8b614d8860 100644 --- a/lib/tools/doc/src/eprof.xml +++ b/lib/tools/doc/src/eprof.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>1996</year><year>2010</year> + <year>1996</year><year>2011</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -147,7 +147,7 @@ </type> <desc> <p>This function ensures that the results displayed by - <c>analyse/0</c> and <c>total_analyse/0</c> are printed both to + <c>analyze/0,1,2</c> are printed both to the file <c>File</c> and the screen.</p> </desc> </func> diff --git a/lib/tools/doc/src/make.dep b/lib/tools/doc/src/make.dep deleted file mode 100644 index 11fa090d6f..0000000000 --- a/lib/tools/doc/src/make.dep +++ /dev/null @@ -1,33 +0,0 @@ -# ---------------------------------------------------- -# >>>> Do not edit this file <<<< -# This file was automaticly generated by -# /home/otp/bin/docdepend -# ---------------------------------------------------- - - -# ---------------------------------------------------- -# TeX files that the DVI file depend on -# ---------------------------------------------------- - -book.dvi: book.tex cover.tex cover_chapter.tex cprof.tex \ - cprof_chapter.tex eprof.tex erlang_mode.tex \ - erlang_mode_chapter.tex fprof.tex fprof_chapter.tex \ - instrument.tex make.tex part.tex ref_man.tex \ - tags.tex xref.tex xref_chapter.tex - -# ---------------------------------------------------- -# Source inlined when transforming from source to LaTeX -# ---------------------------------------------------- - -book.tex: ref_man.xml - -cprof.tex: ../../../../system/doc/definitions/term.defs - -xref.tex: ../../../../system/doc/definitions/term.defs - -# ---------------------------------------------------- -# Pictures that the DVI file depend on -# ---------------------------------------------------- - -book.dvi: venn1.ps venn2.ps - diff --git a/lib/tools/doc/src/notes.xml b/lib/tools/doc/src/notes.xml index 17506fb6e2..e24e1c5977 100644 --- a/lib/tools/doc/src/notes.xml +++ b/lib/tools/doc/src/notes.xml @@ -30,6 +30,85 @@ </header> <p>This document describes the changes made to the Tools application.</p> +<section><title>Tools 2.6.6.6</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>Update system profiling principles to reflect eprof + performance improvements.</p> + <p> + Own Id: OTP-9656</p> + </item> + <item> + <p> + [cover] fix leftover {'DOWN', ..} msg in callers queue</p> + <p> + After stopping cover with cover:stop() there could still + be a {'DOWN',...} leftover message in the calling + process's message queue. This unexpected leftover could + be eliminated if erlang:demonitor/2 with option flush + would be used in certain points</p> + <p> + Own Id: OTP-9694</p> + </item> + <item> + <p> + Add deps as erlang-flymake include directory.</p> + <p> + Update erlang-flymake to recognize the "deps" folder as + an include directory. This makes erlang-flymake + compatible with the rebar dependency management tool's + default folder structure, which puts included + dependencies in "deps".(Thanks to Kevin Albrecht)</p> + <p> + Own Id: OTP-9791</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p>Variables are now now allowed in '<c>fun M:F/A</c>' as + suggested by Richard O'Keefe in EEP-23.</p> + <p>The representation of '<c>fun M:F/A</c>' in the + abstract format has been changed in an incompatible way. + Tools that directly read or manipulate the abstract + format (such as parse transforms) may need to be updated. + The compiler can handle both the new and the old format + (i.e. extracting the abstract format from a pre-R15 BEAM + file and compiling it using compile:forms/1,2 will work). + The <c>syntax_tools</c> application can also handle both + formats.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-9643</p> + </item> + <item> + <p> + Tuple funs (a two-element tuple with a module name and a + function) are now officially deprecated and will be + removed in R16. Use '<c>fun M:F/A</c>' instead. To make + you aware that your system uses tuple funs, the very + first time a tuple fun is applied, a warning will be sent + to the error logger.</p> + <p> + Own Id: OTP-9649</p> + </item> + <item> + <p> + Eliminate use of deprecated regexp module</p> + <p> + Own Id: OTP-9810</p> + </item> + </list> + </section> + +</section> + <section><title>Tools 2.6.6.5</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/tools/emacs/erlang-flymake.el b/lib/tools/emacs/erlang-flymake.el index bc368e9454..2e447b55de 100644 --- a/lib/tools/emacs/erlang-flymake.el +++ b/lib/tools/emacs/erlang-flymake.el @@ -60,7 +60,8 @@ check on newline and when there are no changes)." (list (concat (erlang-flymake-get-app-dir) "ebin"))) (defun erlang-flymake-get-include-dirs () - (list (concat (erlang-flymake-get-app-dir) "include"))) + (list (concat (erlang-flymake-get-app-dir) "include") + (concat (erlang-flymake-get-app-dir) "deps"))) (defun erlang-flymake-get-app-dir () (let ((src-path (file-name-directory (buffer-file-name)))) diff --git a/lib/tools/src/cover.erl b/lib/tools/src/cover.erl index fb9744d759..e21bd1b88c 100644 --- a/lib/tools/src/cover.erl +++ b/lib/tools/src/cover.erl @@ -522,7 +522,7 @@ call(Request) -> {?SERVER,Reply} -> Reply end, - erlang:demonitor(Ref), + erlang:demonitor(Ref, [flush]), Return end. @@ -545,7 +545,7 @@ remote_call(Node,Request) -> {?SERVER,Reply} -> Reply end, - erlang:demonitor(Ref), + erlang:demonitor(Ref, [flush]), Return end. diff --git a/lib/tools/src/fprof.erl b/lib/tools/src/fprof.erl index 155965a65a..8165a6c13a 100644 --- a/lib/tools/src/fprof.erl +++ b/lib/tools/src/fprof.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2001-2009. All Rights Reserved. +%% Copyright Ericsson AB 2001-2011. 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 @@ -87,8 +87,10 @@ dbg(_, _, _) -> -apply({M, F} = Function, Args) +apply({M, F}, Args) when is_atom(M), is_atom(F), is_list(Args) -> + Arity = length(Args), + Function = fun M:F/Arity, apply_1(Function, Args, []); apply(Fun, Args) when is_function(Fun), is_list(Args) -> @@ -98,8 +100,10 @@ apply(A, B) -> apply(M, F, Args) when is_atom(M), is_atom(F), is_list(Args) -> apply_1({M, F}, Args, []); -apply({M, F} = Function, Args, Options) +apply({M, F}, Args, Options) when is_atom(M), is_atom(F), is_list(Args), is_list(Options) -> + Arity = length(Args), + Function = fun M:F/Arity, apply_1(Function, Args, Options); apply(Fun, Args, Options) when is_function(Fun), is_list(Args), is_list(Options) -> @@ -109,7 +113,9 @@ apply(A, B, C) -> apply(Module, Function, Args, Options) when is_atom(Module), is_atom(Function), is_list(Args), is_list(Options) -> - apply_1({Module, Function}, Args, Options); + Arity = length(Args), + Fun = fun Module:Function/Arity, + apply_1(Fun, Args, Options); apply(A, B, C, D) -> erlang:error(badarg, [A, B, C, D]). diff --git a/lib/tools/src/xref_compiler.erl b/lib/tools/src/xref_compiler.erl index 1445e135be..22312c6754 100644 --- a/lib/tools/src/xref_compiler.erl +++ b/lib/tools/src/xref_compiler.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2000-2010. All Rights Reserved. +%% Copyright Ericsson AB 2000-2011. 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 @@ -736,8 +736,11 @@ find_nodes(Tuple, I, T) when is_tuple(Tuple) -> end, {NL, NI, T1} = foldl(Fun, {[], I, T}, L), Tag = case Tag0 of - _ when is_function(Tag0) -> Tag0; - _ when is_atom(Tag0) -> {sofs, Tag0} + _ when is_function(Tag0) -> + Tag0; + _ when is_atom(Tag0) -> + Arity = length(NL), + fun sofs:Tag0/Arity end, find_node({apply, Tag, NL}, NI, T1). diff --git a/lib/tools/src/xref_reader.erl b/lib/tools/src/xref_reader.erl index d22f0df164..92f0c45c7b 100644 --- a/lib/tools/src/xref_reader.erl +++ b/lib/tools/src/xref_reader.erl @@ -158,15 +158,20 @@ expr({'try',_Line,Es,Scs,Ccs,As}, S) -> S2 = clauses(Scs, S1), S3 = clauses(Ccs, S2), expr(As, S3); -expr({call, Line, - {remote, _, {atom,_,erlang}, {atom,_,make_fun}}, - [{atom,_,Mod}, {atom,_,Fun}, {integer,_,Arity}]}, S) -> - %% Added in R10B-6. M:F/A. - expr({'fun', Line, {function, Mod, Fun, Arity}}, S); -expr({'fun', Line, {function, Mod, Name, Arity}}, S) -> - %% Added in R10B-6. M:F/A. +expr({'fun', Line, {function, {atom,_,Mod}, + {atom,_,Name}, + {integer,_,Arity}}}, S) -> + %% New format in R15. M:F/A (literals). As = lists:duplicate(Arity, {atom, Line, foo}), external_call(Mod, Name, As, Line, false, S); +expr({'fun', Line, {function, Mod, Name, {integer,_,Arity}}}, S) -> + %% New format in R15. M:F/A (one or more variables). + As = lists:duplicate(Arity, {atom, Line, foo}), + external_call(erlang, apply, [Mod, Name, list2term(As)], Line, true, S); +expr({'fun', Line, {function, Mod, Name, _Arity}}, S) -> + %% New format in R15. M:F/A (one or more variables). + As = {var, Line, '_'}, + external_call(erlang, apply, [Mod, Name, As], Line, true, S); expr({'fun', Line, {function, Name, Arity}, _Extra}, S) -> %% Added in R8. handle_call(local, S#xrefr.module, Name, Arity, Line, S); @@ -286,10 +291,10 @@ check_funarg(W, ArgsList, Line, S) -> expr(ArgsList, S1). funarg({'fun', _, _Clauses, _Extra}, _S) -> true; -funarg({var, _, Var}, S) -> member(Var, S#xrefr.funvars); -funarg({call,_,{remote,_,{atom,_,erlang},{atom,_,make_fun}},_MFA}, _S) -> - %% R10B-6. M:F/A. +funarg({'fun', _, {function,_,_,_}}, _S) -> + %% New abstract format for fun M:F/A in R15. true; +funarg({var, _, Var}, S) -> member(Var, S#xrefr.funvars); funarg(_, _S) -> false. fun_args(apply2, [FunArg, Args]) -> {FunArg, Args}; diff --git a/lib/tools/test/cover_SUITE.erl b/lib/tools/test/cover_SUITE.erl index fe7f92de78..576d7e261c 100644 --- a/lib/tools/test/cover_SUITE.erl +++ b/lib/tools/test/cover_SUITE.erl @@ -130,13 +130,20 @@ compile(Config) when is_list(Config) -> ?line {ok,_} = compile:file(x), ?line {ok,_} = compile:file("d/y",[debug_info,{outdir,"d"},report]), ?line Key = "A Krypto Key", - ?line {ok,_} = compile:file(crypt, [debug_info,{debug_info_key,Key},report]), + CryptoWorks = crypto_works(), + case CryptoWorks of + false -> + {ok,_} = compile:file(crypt, [debug_info,report]), + {ok,crypt} = cover:compile_beam("crypt.beam"); + true -> + {ok,_} = compile:file(crypt, [{debug_info_key,Key},report]), + {error,{encrypted_abstract_code,_}} = + cover:compile_beam("crypt.beam"), + ok = beam_lib:crypto_key_fun(simple_crypto_fun(Key)), + {ok,crypt} = cover:compile_beam("crypt.beam") + end, ?line {ok,v} = cover:compile_beam(v), ?line {ok,w} = cover:compile_beam("w.beam"), - ?line {error,{encrypted_abstract_code,_}} = - cover:compile_beam("crypt.beam"), - ?line ok = beam_lib:crypto_key_fun(simple_crypto_fun(Key)), - ?line {ok,crypt} = cover:compile_beam("crypt.beam"), ?line {error,{no_abstract_code,"./x.beam"}} = cover:compile_beam(x), ?line {error,{already_cover_compiled,no_beam_found,a}}=cover:compile_beam(a), ?line {error,non_existing} = cover:compile_beam(z), @@ -148,6 +155,15 @@ compile(Config) when is_list(Config) -> ?line Files = lsfiles(), ?line remove(files(Files, ".beam")). +crypto_works() -> + try crypto:start() of + {error,{already_started,crypto}} -> true; + ok -> true + catch + error:_ -> + false + end. + simple_crypto_fun(Key) -> fun(init) -> ok; ({debug_info, des3_cbc, crypt, _}) -> Key @@ -583,21 +599,14 @@ otp_6115_1(Config) -> %% called -- running cover compiled code when there is no cover %% server and thus no ets tables to bump counters in, makes no %% sense. - ?line Pid1 = f1:start_fail(), - - %% If f1 is cover compiled, a process P is started with a - %% reference to the fun created in start_ok/0, and - %% cover:stop() is called, then P should survive. - %% This is because (the fun held by) P always references the current - %% version of the module, and is thus not affected by the cover - %% compiled version being unloaded. - ?line Pid2 = f1:start_ok(), + Pid1 = f1:start_a(), + Pid2 = f1:start_b(), %% Now stop cover ?line cover:stop(), - %% Ensure that f1 is loaded (and not cover compiled), that Pid1 - %% is dead and Pid2 is alive, but with no reference to old code + %% Ensure that f1 is loaded (and not cover compiled), and that + %% both Pid1 and Pid2 are dead. case code:which(f1) of Beam when is_list(Beam) -> ok; @@ -608,19 +617,15 @@ otp_6115_1(Config) -> undefined -> ok; _PI1 -> - RefToOldP = erlang:check_process_code(Pid1, f1), - ?line ?t:fail({"Pid1 still alive", RefToOldP}) + RefToOldP1 = erlang:check_process_code(Pid1, f1), + ?t:fail({"Pid1 still alive", RefToOldP1}) end, case process_info(Pid2) of - PI2 when is_list(PI2) -> - case erlang:check_process_code(Pid2, f2) of - false -> - ok; - true -> - ?line ?t:fail("Pid2 has ref to old code") - end; undefined -> - ?line ?t:fail("Pid2 has died") + ok; + _PI2 -> + RefToOldP2 = erlang:check_process_code(Pid1, f2), + ?t:fail({"Pid2 still alive", RefToOldP2}) end, ?line file:set_cwd(CWD), diff --git a/lib/tools/test/cover_SUITE_data/otp_6115/f1.erl b/lib/tools/test/cover_SUITE_data/otp_6115/f1.erl index b659e5d818..5399b33f19 100644 --- a/lib/tools/test/cover_SUITE_data/otp_6115/f1.erl +++ b/lib/tools/test/cover_SUITE_data/otp_6115/f1.erl @@ -1,12 +1,13 @@ -module(f1). --export([start_fail/0, start_ok/0]). +-export([start_a/0, start_b/0]). -start_fail() -> +start_a() -> f2:start(fun() -> - io:format("this does not work\n",[]) + ok end). -start_ok() -> +start_b() -> f2:start(fun fun1/0). + fun1() -> - io:format("this works\n",[]). + ok. diff --git a/lib/tools/test/eprof_SUITE.erl b/lib/tools/test/eprof_SUITE.erl index ecdbc5ce57..3283fa571f 100644 --- a/lib/tools/test/eprof_SUITE.erl +++ b/lib/tools/test/eprof_SUITE.erl @@ -183,8 +183,14 @@ eed(Config) when is_list(Config) -> ?line ok = eprof:log("eprof_SUITE_logfile"), ?line stopped = eprof:stop(), ?line ?t:timetrap_cancel(TTrap), - S = lists:flatten(io_lib:format("~p times slower", [10*(T3-T2)/(T2-T1)])), - {comment,S}. + try + S = lists:flatten(io_lib:format("~p times slower", + [10*(T3-T2)/(T2-T1)])), + {comment,S} + catch + error:badarith -> + {comment,"No time elapsed. Bad clock? Fast computer?"} + end. ensure_eprof_stopped() -> Pid = whereis(eprof), diff --git a/lib/tools/test/eprof_SUITE_data/ed.script b/lib/tools/test/eprof_SUITE_data/ed.script index 94531a9e98..fe1625bc50 100644 --- a/lib/tools/test/eprof_SUITE_data/ed.script +++ b/lib/tools/test/eprof_SUITE_data/ed.script @@ -1,5 +1,7 @@ H r eed.erl +1,$s/Created :/Skapad :/p +/^cmd_line/,/^file/-1p g/^[a-z][a-zA-Z_]*\(/i\ %%% -------------------------------------------------------------\ %%% A stupid function header.\ diff --git a/lib/tools/test/eprof_SUITE_data/eed.erl b/lib/tools/test/eprof_SUITE_data/eed.erl index 0175abdd0e..520c5f3dd1 100644 --- a/lib/tools/test/eprof_SUITE_data/eed.erl +++ b/lib/tools/test/eprof_SUITE_data/eed.erl @@ -10,6 +10,8 @@ -export([edit/0, edit/1, file/1, cmd_line/1]). +-compile({no_auto_import,[error/1]}). + -record(state, {dot = 0, % Line number of dot. upto_dot = [], % Lines up to dot (reversed). after_dot = [], % Lines after dot. @@ -60,7 +62,7 @@ loop(St0) -> ok; {error, Reason} -> loop(print_error(Reason, St1)); - St2 when record(St2, state) -> + St2 when is_record(St2, state) -> loop(St2) end. @@ -68,7 +70,7 @@ command(Cmd, St) -> case parse_command(Cmd, St) of quit -> quit; - St1 when function(St1#state.print) -> + St1 when is_function(St1#state.print) -> if St1#state.dot /= 0 -> print_current(St1); @@ -76,7 +78,7 @@ command(Cmd, St) -> ok end, St1#state{print=false}; - St1 when record(St1, state) -> + St1 when is_record(St1, state) -> St1 end. @@ -103,13 +105,13 @@ get_input([C|Rest], St, Result) -> get_line1(Io, Prompt, Result) -> get_line2(Io, io:get_line(Io, Prompt), Result). -get_line2(Io, eof, []) -> +get_line2(_Io, eof, []) -> eof; -get_line2(Io, eof, Result) -> +get_line2(_Io, eof, Result) -> lists:reverse(Result); get_line2(Io, [$\\, $\n], Result) -> get_line1(Io, '', [$\n|Result]); -get_line2(Io, [$\n], Result) -> +get_line2(_Io, [$\n], Result) -> lists:reverse(Result, [$\n]); get_line2(Io, [C|Rest], Result) -> get_line2(Io, Rest, [C|Result]). @@ -193,7 +195,7 @@ get_one1([$+|Rest], Sum, St) -> get_one2({ok, 1, Rest}, 1, Sum, St); get_one1([$-|Rest], Sum, St) -> get_one2({ok, 1, Rest}, -1, Sum, St); -get_one1(Cmd, false, St) -> +get_one1(_Cmd, false, _St) -> false; get_one1(Cmd, Sum, St) -> {ok, Sum, Cmd, St}. @@ -222,13 +224,13 @@ get_address([$', Mark|Rest], St) when $a =< Mark, Mark =< $z -> false -> {ok, 0, Rest, St} end; -get_address([$'|Rest], State) -> +get_address([$'|_Rest], _State) -> error(bad_mark); get_address([$/|Rest], State) -> scan_forward($/, Rest, State); -get_address([$?|Rest], State) -> +get_address([$?|_Rest], _State) -> error(not_implemented); -get_address(Cmd, St) -> +get_address(_Cmd, _St) -> false. scan_forward(End, Patt0, State) -> @@ -238,8 +240,8 @@ scan_forward(End, Patt0, State) -> scan_forward1(Dot+1, After, NewState, Rest). scan_forward1(Linenum, [Line|Rest], State, RestCmd) -> - case regexp:first_match(Line#line.contents, State#state.pattern) of - {match, _, _} -> + case re:run(Line#line.contents, State#state.pattern, [{capture, none}]) of + match -> {ok, Linenum, RestCmd, State}; nomatch -> scan_forward1(Linenum+1, Rest, State, RestCmd) @@ -254,13 +256,14 @@ scan_forward1(_, [], State, RestCmd) -> Other end. -scan_forward2(0, [], State, RestCmd) -> +scan_forward2(0, [], _State, _RestCmd) -> false; scan_forward2(Linenum, [Line|Rest], State, RestCmd) -> case scan_forward2(Linenum-1, Rest, State, RestCmd) of false -> - case regexp:first_match(Line#line.contents, State#state.pattern) of - {match, _, _} -> + case re:run(Line#line.contents, State#state.pattern, + [{capture, none}]) of + match -> {ok, Linenum, RestCmd, State}; nomatch -> false @@ -296,7 +299,7 @@ parse_cmd_char($t, Cont) -> Cont(fun transpose_command/3, 2, dot); parse_cmd_char($u, Cont) -> Cont(fun undo_command/3, 0, none); parse_cmd_char($v, Cont) -> Cont(fun vglobal_command/3, 2, all); parse_cmd_char($w, Cont) -> Cont(fun write_command/3, 2, all); -parse_cmd_char(_, Cont) -> error(bad_command). +parse_cmd_char(_, _Cont) -> error(bad_command). execute_command(Fun, NumLines, Def, State, Nums, Rest) -> Lines = check_lines(NumLines, Def, Nums, State), @@ -380,7 +383,7 @@ change_command(Rest, Lines, St0) -> %% (.,.)d - delete lines -delete_command(Rest, [0, Last], St) -> +delete_command(_Rest, [0, _Last], _St) -> error(bad_linenum); delete_command(Rest, [First, Last], St0) -> St1 = check_trailing_p(Rest, save_for_undo(St0)), @@ -396,7 +399,7 @@ delete(Left, St0) -> %% e file - replace buffer with new file -enter_command(Name, [], St) when St#state.modified == true -> +enter_command(_Name, [], St) when St#state.modified == true -> error(buffer_modified); enter_command(Name, [], St0) -> enter_always_command(Name, [], St0). @@ -439,7 +442,7 @@ mark(Sense, [First, Last], St0) -> St1 = move_to(Last, St0), mark1(Sense, First-1, St1). -mark1(Sense, First, St) when St#state.dot == First -> +mark1(_Sense, First, St) when St#state.dot == First -> St; mark1(Sense, First, St) -> [Line|Prev] = St#state.upto_dot, @@ -507,16 +510,16 @@ help_always_command([], [], St) -> %% (.)i - insert text -insert_command(Rest, [0], State) -> +insert_command(_Rest, [0], _State) -> error(bad_linenum); insert_command(Rest, [Line], State) -> append_command(Rest, [Line-1], State). %% (.)kx - mark line -mark_command(_, [0], St) -> +mark_command(_, [0], _St) -> error(bad_linenum); -mark_command([Mark|Rest], [Line], St) when $a =< Mark, Mark =< $z -> +mark_command([Mark|_Rest], [_Line], _St) when $a =< Mark, Mark =< $z -> error(not_implemented); mark_command(_, _, _) -> error(bad_mark). @@ -528,12 +531,12 @@ list_command(Rest, Lines, St) -> %% (.,.)m - move lines -move_command(Cmd, [First, Last], St) -> +move_command(_Cmd, [_First, _Last], _St) -> error(not_implemented). %% (.,.)t - copy lines -transpose_command(Cmd, [First, Last], St) -> +transpose_command(_Cmd, [_First, _Last], _St) -> error(not_implemented). %% (.,.)n - print lines with line numbers @@ -604,39 +607,41 @@ read(After, Name, St0) -> subst_command(_, [0, _], _) -> error(bad_linenum); -subst_command([$ |Cmd0], [First, Last], St0) -> +subst_command([$ |_Cmd0], [_First, _Last], _St0) -> error(bad_delimiter); -subst_command([$\n|Cmd0], [First, Last], St0) -> +subst_command([$\n|_Cmd0], [_First, _Last], _St0) -> error(bad_delimiter); subst_command([Sep|Cmd0], [First, Last], St0) -> St1 = save_for_undo(St0), {ok, Cmd1, St2} = get_pattern(Sep, Cmd0, St1), {ok, Replacement, Cmd2} = get_replacement(Sep, Cmd1), - {ok, Sub, Cmd3} = subst_check_gflag(Cmd2), + {ok, Opts, Cmd3} = subst_check_gflag(Cmd2), St3 = check_trailing_p(Cmd3, St2), - subst_command(Last-First+1, Sub, Replacement, move_to(First-1, St3), nomatch); + subst_command(Last-First+1, Opts, Replacement, + move_to(First-1, St3), nomatch); subst_command([], _, _) -> error(bad_delimiter). subst_command(0, _, _, _, nomatch) -> error(nomatch); -subst_command(0, _, _, _, StLast) when record(StLast, state) -> +subst_command(0, _, _, _, StLast) when is_record(StLast, state) -> StLast; -subst_command(Left, Sub, Repl, St0, LastMatch) -> +subst_command(Left, Opts, Repl, St0, LastMatch) -> St1 = next_line(St0), [Line|_] = St1#state.upto_dot, - case regexp:Sub(Line#line.contents, St1#state.pattern, Repl) of - {ok, _, 0} -> - subst_command(Left-1, Sub, Repl, St1, LastMatch); - {ok, NewContents, _} -> + Contents = Line#line.contents, + case re:replace(Contents, St1#state.pattern, Repl, Opts) of + Contents -> + subst_command(Left-1, Opts, Repl, St1, LastMatch); + NewContents -> %% XXX This doesn't work with marks. St2 = delete_current_line(St1), St3 = insert_line(NewContents, St2), - subst_command(Left-1, Sub, Repl, St3, St3) + subst_command(Left-1, Opts, Repl, St3, St3) end. -subst_check_gflag([$g|Cmd]) -> {ok, gsub, Cmd}; -subst_check_gflag(Cmd) -> {ok, sub, Cmd}. +subst_check_gflag([$g|Cmd]) -> {ok, [global,{return,list}], Cmd}; +subst_check_gflag(Cmd) -> {ok, [{return,list}], Cmd}. %% u - undo @@ -649,7 +654,7 @@ undo_command(_, _, _) -> %% (1,$)w - write buffer to file -write_command(Cmd, [First, Last], St) -> +write_command(_Cmd, [_First, _Last], _St) -> error(not_implemented). @@ -721,7 +726,7 @@ get_pattern(End, Cmd, State) -> get_pattern(End, [End|Rest], State, []) when State#state.pattern /= undefined -> {ok, Rest, State}; get_pattern(End, [End|Rest], State, Result) -> - case regexp:parse(lists:reverse(Result)) of + case re:compile(lists:reverse(Result)) of {error, _} -> error(bad_pattern); {ok, Re} -> @@ -754,7 +759,7 @@ check_trailing_p([$p], St) -> St#state{print=fun(Line, _) -> io:put_chars(Line) end}; check_trailing_p([], State) -> State; -check_trailing_p(Other, State) -> +check_trailing_p(_Other, _State) -> error(garbage_after_command). error(Reason) -> @@ -765,9 +770,9 @@ match(State) when State#state.dot == 0 -> match(State) -> [Line|_] = State#state.upto_dot, Re = State#state.pattern, - case regexp:first_match(Line#line.contents, Re) of - {match, _, _} -> true; - nomatch -> false + case re:run(Line#line.contents, Re, [{capture, none}]) of + match -> true; + nomatch -> false end. skip_blanks([$ |Rest]) -> diff --git a/lib/tools/test/lcnt_SUITE.erl b/lib/tools/test/lcnt_SUITE.erl index f2afa60e33..1bee6021ab 100644 --- a/lib/tools/test/lcnt_SUITE.erl +++ b/lib/tools/test/lcnt_SUITE.erl @@ -34,7 +34,7 @@ ]). %% Default timetrap timeout (set in init_per_testcase) --define(default_timeout, ?t:minutes(2)). +-define(default_timeout, ?t:minutes(4)). init_per_suite(Config) when is_list(Config) -> Config. @@ -49,6 +49,7 @@ init_per_testcase(_Case, Config) -> end_per_testcase(_Case, Config) -> Dog = ?config(watchdog, Config), ?t:timetrap_cancel(Dog), + catch lcnt:stop(), ok. suite() -> [{ct_hooks,[ts_install_cth]}]. diff --git a/lib/tools/test/xref_SUITE.erl b/lib/tools/test/xref_SUITE.erl index 2f83ab4995..e0876381ca 100644 --- a/lib/tools/test/xref_SUITE.erl +++ b/lib/tools/test/xref_SUITE.erl @@ -46,7 +46,8 @@ -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, qlc/1]). + abstract_modules/1, fun_mfa/1, fun_mfa_r14/1, + fun_mfa_vars/1, qlc/1]). -export([ analyze/1, basic/1, md/1, q/1, variables/1, unused_locals/1]). @@ -82,7 +83,7 @@ groups() -> {files, [], [add, default, info, lib, read, read2, remove, replace, update, deprecated, trycatch, abstract_modules, fun_mfa, - qlc]}, + fun_mfa_r14, fun_mfa_vars, qlc]}, {analyses, [], [analyze, basic, md, q, variables, unused_locals]}, {misc, [], [format_error, otp_7423, otp_7831]}]. @@ -1771,6 +1772,88 @@ fun_mfa(Conf) when is_list(Conf) -> ?line ok = file:delete(Beam), ok. +%% Same as the previous test case, except that we use a BEAM file +%% that was compiled by an R14 compiler to test backward compatibility. +fun_mfa_r14(Conf) when is_list(Conf) -> + Dir = ?config(data_dir, Conf), + MFile = fname(Dir, "fun_mfa_r14"), + + A = fun_mfa_r14, + {ok, _} = xref:start(s), + {ok, A} = xref:add_module(s, MFile, {warnings,false}), + {ok, [{{{A,t,0},{'$M_EXPR','$F_EXPR',0}},[7]}, + {{{A,t,0},{A,t,0}},[6]}, + {{{A,t1,0},{'$M_EXPR','$F_EXPR',0}},[11]}, + {{{A,t1,0},{A,t,0}},[10]}, + {{{A,t2,0},{A,t,0}},[14]}, + {{{A,t3,0},{A,t3,0}},[17]}]} = + xref:q(s, "(Lin) E"), + + ok = check_state(s), + xref:stop(s), + + ok. + +%% fun M:F/A with varibles. +fun_mfa_vars(Conf) when is_list(Conf) -> + Dir = ?copydir, + File = fname(Dir, "fun_mfa_vars.erl"), + MFile = fname(Dir, "fun_mfa_vars"), + Beam = fname(Dir, "fun_mfa_vars.beam"), + Test = <<"-module(fun_mfa_vars). + + -export([t/1, t1/1, t2/3]). + + t(Mod) -> + F = fun Mod:bar/2, + (F)(a, b). + + t1(Name) -> + F = fun ?MODULE:Name/1, + (F)(a). + + t2(Mod, Name, Arity) -> + F = fun Mod:Name/Arity, + (F)(a). + + t3(Arity) -> + F = fun ?MODULE:t/Arity, + (F)(1, 2, 3). + + t4(Mod, Name) -> + F = fun Mod:Name/3, + (F)(a, b, c). + + t5(Mod, Arity) -> + F = fun Mod:t/Arity, + (F)(). + ">>, + + ok = file:write_file(File, Test), + A = fun_mfa_vars, + {ok, A} = compile:file(File, [report,debug_info,{outdir,Dir}]), + {ok, _} = xref:start(s), + {ok, A} = xref:add_module(s, MFile, {warnings,false}), + {ok, [{{{A,t,1},{'$M_EXPR','$F_EXPR',2}},[7]}, + {{{A,t,1},{'$M_EXPR',bar,2}},[6]}, + {{{A,t1,1},{'$M_EXPR','$F_EXPR',1}},[11]}, + {{{A,t1,1},{A,'$F_EXPR',1}},[10]}, + {{{A,t2,3},{'$M_EXPR','$F_EXPR',-1}},[14]}, + {{{A,t2,3},{'$M_EXPR','$F_EXPR',1}},[15]}, + {{{A,t3,1},{'$M_EXPR','$F_EXPR',3}},[19]}, + {{{A,t3,1},{fun_mfa_vars,t,-1}},[18]}, + {{{A,t4,2},{'$M_EXPR','$F_EXPR',3}},[22,23]}, + {{{A,t5,2},{'$M_EXPR','$F_EXPR',0}},[27]}, + {{{A,t5,2},{'$M_EXPR',t,-1}},[26]}]} = + xref:q(s, "(Lin) E"), + + ok = check_state(s), + xref:stop(s), + + ok = file:delete(File), + ok = file:delete(Beam), + ok. + qlc(suite) -> []; qlc(doc) -> ["OTP-5195: A bug fix when using qlc:q/1,2."]; qlc(Conf) when is_list(Conf) -> diff --git a/lib/tools/test/xref_SUITE_data/fun_mfa_r14.beam b/lib/tools/test/xref_SUITE_data/fun_mfa_r14.beam Binary files differnew file mode 100644 index 0000000000..4645525690 --- /dev/null +++ b/lib/tools/test/xref_SUITE_data/fun_mfa_r14.beam diff --git a/lib/tools/test/xref_SUITE_data/fun_mfa_r14.erl b/lib/tools/test/xref_SUITE_data/fun_mfa_r14.erl new file mode 100644 index 0000000000..293bd83a8b --- /dev/null +++ b/lib/tools/test/xref_SUITE_data/fun_mfa_r14.erl @@ -0,0 +1,18 @@ +-module(fun_mfa_r14). + +-export([t/0, t1/0, t2/0, t3/0]). + +t() -> + F = fun ?MODULE:t/0, + (F)(). + +t1() -> + F = fun t/0, + (F)(). + +t2() -> + fun ?MODULE:t/0(). + +t3() -> + fun t3/0(). + diff --git a/lib/tools/vsn.mk b/lib/tools/vsn.mk index 2d63a33554..269d3d7773 100644 --- a/lib/tools/vsn.mk +++ b/lib/tools/vsn.mk @@ -1 +1 @@ -TOOLS_VSN = 2.6.6.5 +TOOLS_VSN = 2.6.6.6 |