diff options
Diffstat (limited to 'lib/stdlib')
35 files changed, 682 insertions, 1468 deletions
| diff --git a/lib/stdlib/doc/src/erl_scan.xml b/lib/stdlib/doc/src/erl_scan.xml index 342f491dd0..ee0d6b6033 100644 --- a/lib/stdlib/doc/src/erl_scan.xml +++ b/lib/stdlib/doc/src/erl_scan.xml @@ -40,39 +40,15 @@    </description>    <datatypes>      <datatype> -      <name name="attribute_info"></name> -    </datatype> -    <datatype> -      <name name="attributes"></name> -    </datatype> -    <datatype> -      <name name="attributes_data"></name> -    </datatype> -    <datatype>        <name name="category"></name>      </datatype>      <datatype> -      <name name="column"></name> -    </datatype> -    <datatype>        <name name="error_description"></name>      </datatype>      <datatype>        <name name="error_info"></name>      </datatype>      <datatype> -      <name name="info_line"></name> -    </datatype> -    <datatype> -      <name name="info_location"></name> -    </datatype> -    <datatype> -      <name name="line"></name> -    </datatype> -    <datatype> -      <name name="location"></name> -    </datatype> -    <datatype>        <name name="option"></name>      </datatype>      <datatype> @@ -88,9 +64,6 @@        <name name="token"></name>      </datatype>      <datatype> -      <name name="token_info"></name> -    </datatype> -    <datatype>        <name name="tokens"></name>      </datatype>      <datatype> @@ -122,25 +95,23 @@            <anno>StartLocation</anno>, [])</c>.</p>          <p><c><anno>StartLocation</anno></c> indicates the initial location            when scanning starts. If <c><anno>StartLocation</anno></c> is a line, -          <c>attributes()</c> as well as <c><anno>EndLocation</anno></c> and +          <c>Anno</c> as well as <c><anno>EndLocation</anno></c> and            <c><anno>ErrorLocation</anno></c> will be lines. If            <c><anno>StartLocation</anno></c> is a pair of a line and a column -          <c>attributes()</c> takes the form of an opaque compound +          <c>Anno</c> takes the form of an opaque compound            data type, and <c><anno>EndLocation</anno></c> and            <c><anno>ErrorLocation</anno></c>            will be pairs of a line and a column. The <em>token -          attributes</em> contain information about the column and the +          annotations</em> contain information about the column and the            line where the token begins, as well as the text of the            token (if the <c>text</c> option is given), all of which can -          be accessed by calling <seealso -          marker="#token_info/1">token_info/1,2</seealso>, <seealso -          marker="#attributes_info/1">attributes_info/1,2</seealso>, +          be accessed by calling            <seealso marker="#column/1">column/1</seealso>,            <seealso marker="#line/1">line/1</seealso>,            <seealso marker="#location/1">location/1</seealso>, and            <seealso marker="#text/1">text/1</seealso>.</p>          <p>A <em>token</em> is a tuple containing information about -          syntactic category, the token attributes, and the actual +          syntactic category, the token annotations, and the actual            terminal symbol. For punctuation characters (e.g. <c>;</c>,            <c>|</c>) and reserved words, the category and the symbol            coincide, and the token is represented by a two-tuple. @@ -172,7 +143,7 @@          <item><p>Short for <c>[return_comments, return_white_spaces]</c>.</p>          </item>          <tag><c>text</c></tag> -        <item><p>Include the token's text in the token attributes. The +        <item><p>Include the token's text in the token annotation. The            text is the part of the input corresponding to the token.</p>          </item>          </taglist> @@ -306,150 +277,6 @@        </desc>      </func>      <func> -      <name name="token_info" arity="1"/> -      <fsummary>Return information about a token</fsummary> -      <desc> -        <p>Returns a list containing information about the token -          <c><anno>Token</anno></c>. The order of the -          <c><anno>TokenInfoTuple</anno></c>s is not -          defined. See <seealso -          marker="#token_info/2">token_info/2</seealso> for -          information about specific -          <c><anno>TokenInfoTuple</anno></c>s.</p> -        <p>Note that if <c>token_info(Token, TokenItem)</c> returns -          <c>undefined</c> for some <c>TokenItem</c>, the -          item is not included in <c><anno>TokenInfo</anno></c>.</p> -      </desc> -    </func> -    <func> -      <name name="token_info" arity="2" clause_i="1"/> -      <name name="token_info" arity="2" clause_i="2"/> -      <fsummary>Return information about a token</fsummary> -      <type name="token_item"/> -      <type name="attribute_item"/> -      <desc> -        <p>Returns a list containing information about the token -          <c><anno>Token</anno></c>. If one single -          <c><anno>TokenItem</anno></c> is given the returned value is -          the corresponding -          <c>TokenInfoTuple</c>, or <c>undefined</c> if the -          <c>TokenItem</c> has no value. If a list of -          <c><anno>TokenItem</anno></c>s is given the result is a list of -          <c><anno>TokenInfoTuple</anno></c>. The -          <c><anno>TokenInfoTuple</anno></c>s will -          appear with the corresponding <c><anno>TokenItem</anno></c>s in -          the same order as the <c><anno>TokenItem</anno></c>s -	  appear in the list of <c>TokenItem</c>s. -          <c><anno>TokenItem</anno></c>s with no value are not included -          in the list of <c><anno>TokenInfoTuple</anno></c>.</p> -	<p>The following <c><anno>TokenInfoTuple</anno></c>s with corresponding -	   <c><anno>TokenItem</anno></c>s are valid:</p> -        <taglist> -          <tag><c>{category, </c><seealso marker="#type-category"> -            category()</seealso><c>}</c></tag> -          <item><p>The category of the token.</p> -          </item> -          <tag><c>{column, </c><seealso marker="#type-column"> -            column()</seealso><c>}</c></tag> -          <item><p>The column where the token begins.</p> -          </item> -          <tag><c>{length, integer() > 0}</c></tag> -          <item><p>The length of the token's text.</p> -          </item> -          <tag><c>{line, </c><seealso marker="#type-line"> -            line()</seealso><c>}</c></tag> -          <item><p>The line where the token begins.</p> -          </item> -          <tag><c>{location, </c><seealso marker="#type-location"> -            location()</seealso><c>}</c></tag> -          <item><p>The line and column where the token begins, or -            just the line if the column unknown.</p> -          </item> -          <tag><c>{symbol, </c><seealso marker="#type-symbol"> -            symbol()</seealso><c>}</c></tag> -          <item><p>The token's symbol.</p> -          </item> -          <tag><c>{text, string()}</c></tag> -          <item><p>The token's text.</p> -          </item> -        </taglist> -      </desc> -    </func> -    <func> -      <name name="attributes_info" arity="1"/> -      <fsummary>Return information about token attributes</fsummary> -      <desc> -        <p>Returns a list containing information about the token -          attributes <c><anno>Attributes</anno></c>. The order of the -          <c><anno>AttributeInfoTuple</anno></c>s is not defined. -          See <seealso -          marker="#attributes_info/2">attributes_info/2</seealso> for -          information about specific -          <c><anno>AttributeInfoTuple</anno></c>s.</p> -        <p>Note that if <c>attributes_info(Token, AttributeItem)</c> -          returns <c>undefined</c> for some <c>AttributeItem</c> in -          the list above, the item is not included in -          <c><anno>AttributesInfo</anno></c>.</p> -      </desc> -    </func> -    <func> -      <name name="attributes_info" arity="2" clause_i="1"/> -      <name name="attributes_info" arity="2" clause_i="2"/> -      <fsummary>Return information about a token attributes</fsummary> -      <type name="attribute_item"/> -      <desc> -        <p>Returns a list containing information about the token -          attributes <c><anno>Attributes</anno></c>. If one single -          <c><anno>AttributeItem</anno></c> is given the returned value is the -          corresponding <c><anno>AttributeInfoTuple</anno></c>, -          or <c>undefined</c> if the <c><anno>AttributeItem</anno></c> -          has no value. If a list of <c><anno>AttributeItem</anno></c> -          is given the result is a list of -          <c><anno>AttributeInfoTuple</anno></c>. -          The <c><anno>AttributeInfoTuple</anno></c>s -          will appear with the corresponding <c><anno>AttributeItem</anno></c>s -          in the same order as the <c><anno>AttributeItem</anno></c>s -          appear in the list of <c><anno>AttributeItem</anno></c>s. -          <c><anno>AttributeItem</anno></c>s with no -          value are not included in the list of -	  <c><anno>AttributeInfoTuple</anno></c>.</p> -	<p>The following <c><anno>AttributeInfoTuple</anno></c>s with -          corresponding <c><anno>AttributeItem</anno></c>s are valid:</p> -        <taglist> -          <tag><c>{column, </c><seealso marker="#type-column"> -            column()</seealso><c>}</c></tag> -          <item><p>The column where the token begins.</p> -          </item> -          <tag><c>{length, integer() > 0}</c></tag> -          <item><p>The length of the token's text.</p> -          </item> -          <tag><c>{line, </c><seealso marker="#type-line"> -            line()</seealso><c>}</c></tag> -          <item><p>The line where the token begins.</p> -          </item> -          <tag><c>{location, </c><seealso marker="#type-location"> -            location()</seealso><c>}</c></tag> -          <item><p>The line and column where the token begins, or -            just the line if the column unknown.</p> -          </item> -          <tag><c>{text, string()}</c></tag> -          <item><p>The token's text.</p> -          </item> -        </taglist> -      </desc> -    </func> -    <func> -      <name name="set_attribute" arity="3"/> -      <fsummary>Set a token attribute value</fsummary> -      <desc> -        <p>Sets the value of the <c>line</c> attribute of the token -          attributes <c><anno>Attributes</anno></c>.</p> -        <p>The <c><anno>SetAttributeFun</anno></c> is called with the value of -          the <c>line</c> attribute, and is to return the new value of -          the <c>line</c> attribute.</p> -      </desc> -    </func> -    <func>        <name name="format_error" arity="1"/>        <fsummary>Format an error descriptor</fsummary>        <desc> diff --git a/lib/stdlib/include/erl_bits.hrl b/lib/stdlib/include/erl_bits.hrl index 8405a55d55..2a54587a17 100644 --- a/lib/stdlib/include/erl_bits.hrl +++ b/lib/stdlib/include/erl_bits.hrl @@ -1,7 +1,7 @@  %%  %% %CopyrightBegin%  %%  -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. +%% Copyright Ericsson AB 1999-2015. All Rights Reserved.  %%   %% Licensed under the Apache License, Version 2.0 (the "License");  %% you may not use this file except in compliance with the License. @@ -26,10 +26,10 @@  -type bt_unit()  :: 1..256.  -record(bittype, { -          type   :: bt_type(), -	  unit   :: bt_unit(),       %% element unit -          sign   :: bt_sign(), -          endian :: bt_endian() +          type   :: bt_type() | 'undefined', +	  unit   :: bt_unit() | 'undefined',       %% element unit +          sign   :: bt_sign() | 'undefined', +          endian :: bt_endian() | 'undefined'           }).  -record(bitdefault, { diff --git a/lib/stdlib/src/beam_lib.erl b/lib/stdlib/src/beam_lib.erl index cbbab088f4..6e00401dce 100644 --- a/lib/stdlib/src/beam_lib.erl +++ b/lib/stdlib/src/beam_lib.erl @@ -872,7 +872,7 @@ mandatory_chunks() ->  %%% can use it.  %%% ==================================================================== --record(state, {crypto_key_f :: crypto_fun()}). +-record(state, {crypto_key_f :: crypto_fun() | 'undefined'}).  -define(CRYPTO_KEY_SERVER, beam_lib__crypto_key_server). diff --git a/lib/stdlib/src/binary.erl b/lib/stdlib/src/binary.erl index af00410572..fb0c395d70 100644 --- a/lib/stdlib/src/binary.erl +++ b/lib/stdlib/src/binary.erl @@ -20,7 +20,7 @@  -module(binary).  %%  %% Implemented in this module: --export([split/2,split/3,replace/3,replace/4]). +-export([replace/3,replace/4]).  -export_type([cp/0]). @@ -34,7 +34,8 @@           decode_unsigned/2, encode_unsigned/1, encode_unsigned/2,           first/1, last/1, list_to_bin/1, longest_common_prefix/1,           longest_common_suffix/1, match/2, match/3, matches/2, -         matches/3, part/2, part/3, referenced_byte_size/1]). +         matches/3, part/2, part/3, referenced_byte_size/1, +         split/2, split/3]).  -spec at(Subject, Pos) -> byte() when        Subject :: binary(), @@ -198,19 +199,13 @@ part(_, _, _) ->  referenced_byte_size(_) ->      erlang:nif_error(undef). -%%% End of BIFs. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% split -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -  -spec split(Subject, Pattern) -> Parts when        Subject :: binary(),        Pattern :: binary() | [binary()] | cp(),        Parts :: [binary()]. -split(H,N) -> -    split(H,N,[]). +split(_, _) -> +    erlang:nif_error(undef).  -spec split(Subject, Pattern, Options) -> Parts when        Subject :: binary(), @@ -219,53 +214,10 @@ split(H,N) ->        Option :: {scope, part()} | trim | global | trim_all,        Parts :: [binary()]. -split(Haystack,Needles,Options) -> -    try -	{Part,Global,Trim,TrimAll} = -        get_opts_split(Options,{no,false,false,false}), -	Moptlist = case Part of -		       no -> -			   []; -		       {A,B} -> -			   [{scope,{A,B}}] -		   end, -	MList = if -		    Global -> -			binary:matches(Haystack,Needles,Moptlist); -		    true -> -			case binary:match(Haystack,Needles,Moptlist) of -			    nomatch -> []; -			    Match -> [Match] -			end -		end, -	do_split(Haystack,MList,0,Trim,TrimAll) -    catch -	_:_ -> -	    erlang:error(badarg) -    end. - -do_split(H,[],N,true,_) when N >= byte_size(H) -> -    []; -do_split(H,[],N,_,true) when N >= byte_size(H) -> -    []; -do_split(H,[],N,_,_) -> -    [binary:part(H,{N,byte_size(H)-N})]; -do_split(H,[{A,B}|T],N,Trim,TrimAll) -> -    case binary:part(H,{N,A-N}) of -	<<>> when TrimAll == true -> -	    do_split(H,T,A+B,Trim,TrimAll); -	<<>> -> -	    Rest =  do_split(H,T,A+B,Trim,TrimAll), -	    case {Trim, Rest} of -		{true,[]} -> -		    []; -		_ -> -		    [<<>> | Rest] -	    end; -	Oth -> -	    [Oth | do_split(H,T,A+B,Trim,TrimAll)] -    end. +split(_, _, _) -> +    erlang:nif_error(undef). +%%% End of BIFs.  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  %% replace @@ -352,19 +304,6 @@ splitat(H,N,[I|T]) ->  %% Simple helper functions  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -get_opts_split([],{Part,Global,Trim,TrimAll}) -> -    {Part,Global,Trim,TrimAll}; -get_opts_split([{scope,{A,B}} | T],{_Part,Global,Trim,TrimAll}) -> -    get_opts_split(T,{{A,B},Global,Trim,TrimAll}); -get_opts_split([global | T],{Part,_Global,Trim,TrimAll}) -> -    get_opts_split(T,{Part,true,Trim,TrimAll}); -get_opts_split([trim | T],{Part,Global,_Trim,TrimAll}) -> -    get_opts_split(T,{Part,Global,true,TrimAll}); -get_opts_split([trim_all | T],{Part,Global,Trim,_TrimAll}) -> -    get_opts_split(T,{Part,Global,Trim,true}); -get_opts_split(_,_) -> -    throw(badopt). -  get_opts_replace([],{Part,Global,Insert}) ->      {Part,Global,Insert};  get_opts_replace([{scope,{A,B}} | T],{_Part,Global,Insert}) -> diff --git a/lib/stdlib/src/epp.erl b/lib/stdlib/src/epp.erl index d3124ac593..45f616bb02 100644 --- a/lib/stdlib/src/epp.erl +++ b/lib/stdlib/src/epp.erl @@ -40,7 +40,7 @@  -type ifdef() :: 'ifdef' | 'ifndef' | 'else'. --type name() :: {'atom', atom()}. +-type name() :: atom().  -type argspec() :: 'none'                       %No arguments                   | non_neg_integer().           %Number of arguments  -type tokens() :: [erl_scan:token()]. @@ -49,7 +49,8 @@  -define(DEFAULT_ENCODING, utf8).  %% Epp state record. --record(epp, {file :: file:io_device(),         %Current file +-record(epp, {file :: file:io_device() +                    | 'undefined',              %Current file  	      location=1,         		%Current location                delta=0 :: non_neg_integer(),     %Offset from Location (-file)                name="" :: file:name(),           %Current file name @@ -57,21 +58,14 @@                istk=[] :: [ifdef()],             %Ifdef stack                sstk=[] :: [#epp{}],              %State stack                path=[] :: [file:name()],         %Include-path -              macs = dict:new()                 %Macros (don't care locations) -                  :: dict:dict(name(), {argspec(), tokens()}), -              uses = dict:new()                 %Macro use structure -                  :: dict:dict(name(), [{argspec(), [used()]}]), +              macs = #{}		        %Macros (don't care locations) +	            :: #{name() => {argspec(), tokens()}}, +              uses = #{}			%Macro use structure +	            :: #{name() => [{argspec(), [used()]}]},                default_encoding = ?DEFAULT_ENCODING :: source_encoding(),  	      pre_opened = false :: boolean()  	     }). -%%% Note on representation: as tokens, both {var, Location, Name} and -%%% {atom, Location, Name} can occur as macro identifiers. However, keeping -%%% this distinction here is done for historical reasons only: previously, -%%% ?FOO and ?'FOO' were not the same, but now they are. Removing the -%%% distinction in the internal representation would simplify the code -%%% a little. -  %% open(Options)  %% open(FileName, IncludePath)  %% open(FileName, IncludePath, PreDefMacros) @@ -549,7 +543,8 @@ init_server(Pid, Name, Options, St0) ->  			 default_encoding=DefEncoding},              From = wait_request(St),              Anno = erl_anno:new(AtLocation), -            enter_file_reply(From, Name, Anno, AtLocation, code), +            enter_file_reply(From, file_name(Name), Anno, +			     AtLocation, code),              wait_req_scan(St);  	{error,E} ->  	    epp_reply(Pid, {error,E}) @@ -560,18 +555,18 @@ init_server(Pid, Name, Options, St0) ->  %%  FILE, LINE, MODULE as undefined, MACHINE and MACHINE value.  predef_macros(File) -> -     Machine = list_to_atom(erlang:system_info(machine)), -     Anno = line1(), -     dict:from_list([ -	{{atom,'FILE'}, 	      {none,[{string,Anno,File}]}}, -	{{atom,'LINE'},		      {none,[{integer,Anno,1}]}}, -	{{atom,'MODULE'},	      undefined}, -	{{atom,'MODULE_STRING'},      undefined}, -	{{atom,'BASE_MODULE'},	      undefined}, -	{{atom,'BASE_MODULE_STRING'}, undefined}, -	{{atom,'MACHINE'},	      {none,[{atom,Anno,Machine}]}}, -	{{atom,Machine},	      {none,[{atom,Anno,true}]}} -     ]). +    Machine = list_to_atom(erlang:system_info(machine)), +    Anno = line1(), +    Defs = [{'FILE', 	           {none,[{string,Anno,File}]}}, +	    {'LINE',		   {none,[{integer,Anno,1}]}}, +	    {'MODULE',	           undefined}, +	    {'MODULE_STRING',      undefined}, +	    {'BASE_MODULE',	   undefined}, +	    {'BASE_MODULE_STRING', undefined}, +	    {'MACHINE',	           {none,[{atom,Anno,Machine}]}}, +	    {Machine,	           {none,[{atom,Anno,true}]}} +	   ], +    maps:from_list(Defs).  %% user_predef(PreDefMacros, Macros) ->  %%	{ok,MacroDict} | {error,E} @@ -580,28 +575,21 @@ predef_macros(File) ->  user_predef([{M,Val,redefine}|Pdm], Ms) when is_atom(M) ->      Exp = erl_parse:tokens(erl_parse:abstract(Val)), -    user_predef(Pdm, dict:store({atom,M}, {none,Exp}, Ms)); +    user_predef(Pdm, Ms#{M=>{none,Exp}});  user_predef([{M,Val}|Pdm], Ms) when is_atom(M) -> -    case dict:find({atom,M}, Ms) of -	{ok,_Defs} when is_list(_Defs) -> %% User defined macros +    case Ms of +	#{M:=Defs} when is_list(Defs) -> +	     %% User defined macros.  	    {error,{redefine,M}}; -	{ok,_Def} -> %% Predefined macros +	#{M:=_Defs} -> +	    %% Predefined macros.  	    {error,{redefine_predef,M}}; -	error -> +	_ ->  	    Exp = erl_parse:tokens(erl_parse:abstract(Val)), -	    user_predef(Pdm, dict:store({atom,M}, [{none, {none,Exp}}], Ms)) +	    user_predef(Pdm, Ms#{M=>[{none,{none,Exp}}]})      end;  user_predef([M|Pdm], Ms) when is_atom(M) -> -    case dict:find({atom,M}, Ms) of -	{ok,_Defs} when is_list(_Defs) -> %% User defined macros -	    {error,{redefine,M}}; -	{ok,_Def} -> %% Predefined macros -	    {error,{redefine_predef,M}}; -	error -> -            A = line1(), -	    user_predef(Pdm, -	                dict:store({atom,M}, [{none, {none,[{atom,A,true}]}}], Ms)) -    end; +    user_predef([{M,true}|Pdm], Ms);  user_predef([Md|_Pdm], _Ms) -> {error,{bad,Md}};  user_predef([], Ms) -> {ok,Ms}. @@ -615,7 +603,9 @@ wait_request(St) ->      receive  	{epp_request,From,scan_erl_form} -> From;  	{epp_request,From,macro_defs} -> -	    epp_reply(From, dict:to_list(St#epp.macs)), +	    %% Return the old format to avoid any incompability issues. +	    Defs = [{{atom,K},V} || {K,V} <- maps:to_list(St#epp.macs)], +	    epp_reply(From, Defs),  	    wait_request(St);  	{epp_request,From,close} ->  	    close_file(St), @@ -667,7 +657,8 @@ enter_file(NewName, Inc, From, St) ->  enter_file2(NewF, Pname, From, St0, AtLocation) ->      Anno = erl_anno:new(AtLocation),      enter_file_reply(From, Pname, Anno, AtLocation, code), -    Ms = dict:store({atom,'FILE'}, {none,[{string,Anno,Pname}]}, St0#epp.macs), +    Ms0 = St0#epp.macs, +    Ms = Ms0#{'FILE':={none,[{string,Anno,Pname}]}},      %% update the head of the include path to be the directory of the new      %% source file, so that an included file can always include other files      %% relative to its current location (this is also how C does it); note @@ -688,7 +679,7 @@ enter_file_reply(From, Name, LocationAnno, AtLocation, Where) ->                 generated -> erl_anno:set_generated(true, Anno0)             end,      Rep = {ok, [{'-',Anno},{atom,Anno,file},{'(',Anno}, -		{string,Anno,file_name(Name)},{',',Anno}, +		{string,Anno,Name},{',',Anno},  		{integer,Anno,get_line(LocationAnno)},{')',LocationAnno},                  {dot,Anno}]},      epp_reply(From, Rep). @@ -719,9 +710,8 @@ leave_file(From, St) ->                           name2=OldName2} = OldSt,                      CurrLoc = add_line(OldLoc, Delta),                      Anno = erl_anno:new(CurrLoc), -		    Ms = dict:store({atom,'FILE'}, -				    {none,[{string,Anno,OldName2}]}, -				    St#epp.macs), +		    Ms0 = St#epp.macs, +		    Ms = Ms0#{'FILE':={none,[{string,Anno,OldName2}]}},                      NextSt = OldSt#epp{sstk=Sts,macs=Ms,uses=St#epp.uses},  		    enter_file_reply(From, OldName, Anno, CurrLoc, code),                      case OldName2 =:= OldName of @@ -796,91 +786,48 @@ scan_toks(Toks0, From, St) ->      end.  scan_module([{'-',_Lh},{atom,_Lm,module},{'(',_Ll}|Ts], Ms) -> -    scan_module_1(Ts, [], Ms); +    scan_module_1(Ts, Ms);  scan_module([{'-',_Lh},{atom,_Lm,extends},{'(',_Ll}|Ts], Ms) -> -    scan_extends(Ts, [], Ms); +    scan_extends(Ts, Ms);  scan_module(_Ts, Ms) -> Ms. -scan_module_1([{atom,_,_}=A,{',',L}|Ts], As, Ms) -> +scan_module_1([{atom,_,_}=A,{',',L}|Ts], Ms) ->      %% Parameterized modules. -    scan_module_1([A,{')',L}|Ts], As, Ms); -scan_module_1([{atom,Ln,A},{')',_Lr}|_Ts], As, Ms0) -> -    Mod = lists:concat(lists:reverse([A|As])), -    Ms = dict:store({atom,'MODULE'}, -		     {none,[{atom,Ln,list_to_atom(Mod)}]}, Ms0), -    dict:store({atom,'MODULE_STRING'}, {none,[{string,Ln,Mod}]}, Ms); -scan_module_1([{atom,_Ln,A},{'.',_Lr}|Ts], As, Ms) -> -    scan_module_1(Ts, [".",A|As], Ms); -scan_module_1([{'.',_Lr}|Ts], As, Ms) -> -    scan_module_1(Ts, As, Ms); -scan_module_1(_Ts, _As, Ms) -> Ms. - -scan_extends([{atom,Ln,A},{')',_Lr}|_Ts], As, Ms0) -> -    Mod = lists:concat(lists:reverse([A|As])), -    Ms = dict:store({atom,'BASE_MODULE'}, -		     {none,[{atom,Ln,list_to_atom(Mod)}]}, Ms0), -    dict:store({atom,'BASE_MODULE_STRING'}, {none,[{string,Ln,Mod}]}, Ms); -scan_extends([{atom,_Ln,A},{'.',_Lr}|Ts], As, Ms) -> -    scan_extends(Ts, [".",A|As], Ms); -scan_extends([{'.',_Lr}|Ts], As, Ms) -> -    scan_extends(Ts, As, Ms); -scan_extends(_Ts, _As, Ms) -> Ms. +    scan_module_1([A,{')',L}|Ts], Ms); +scan_module_1([{atom,Ln,A}=ModAtom,{')',_Lr}|_Ts], Ms0) -> +    ModString = atom_to_list(A), +    Ms = Ms0#{'MODULE':={none,[ModAtom]}}, +    Ms#{'MODULE_STRING':={none,[{string,Ln,ModString}]}}; +scan_module_1(_Ts, Ms) -> Ms. + +scan_extends([{atom,Ln,A}=ModAtom,{')',_Lr}|_Ts], Ms0) -> +    ModString = atom_to_list(A), +    Ms = Ms0#{'BASE_MODULE':={none,[ModAtom]}}, +    Ms#{'BASE_MODULE_STRING':={none,[{string,Ln,ModString}]}}; +scan_extends(_Ts, Ms) -> Ms.  %% scan_define(Tokens, DefineToken, From, EppState) -scan_define([{'(',_Lp},{Type,_Lm,M}=Mac,{',',_}=Comma|Toks], _Def, From, St) +scan_define([{'(',_Lp},{Type,_Lm,_}=Mac|Toks], Def, From, St)    when Type =:= atom; Type =:= var -> +    scan_define_1(Toks, Mac, Def, From, St); +scan_define(_Toks, Def, From, St) -> +    epp_reply(From, {error,{loc(Def),epp,{bad,define}}}), +    wait_req_scan(St). + +scan_define_1([{',',_}=Comma|Toks], Mac,_Def, From, St) ->      case catch macro_expansion(Toks, Comma) of          Expansion when is_list(Expansion) -> -            case dict:find({atom,M}, St#epp.macs) of -                {ok, Defs} when is_list(Defs) -> -                    %% User defined macros: can be overloaded -                    case proplists:is_defined(none, Defs) of -                        true -> -                            epp_reply(From, {error,{loc(Mac),epp,{redefine,M}}}), -                            wait_req_scan(St); -                        false -> -                            scan_define_cont(From, St, -                                             {atom, M}, -                                             {none, {none,Expansion}}) -                    end; -                {ok, _PreDef} -> -                    %% Predefined macros: cannot be overloaded -                    epp_reply(From, {error,{loc(Mac),epp,{redefine_predef,M}}}), -                    wait_req_scan(St); -                error -> -                    scan_define_cont(From, St, -                                     {atom, M}, -                                     {none, {none,Expansion}}) -            end; +	    scan_define_2(none, {none,Expansion}, Mac, From, St);          {error,ErrL,What} ->              epp_reply(From, {error,{ErrL,epp,What}}),              wait_req_scan(St)      end; -scan_define([{'(',_Lp},{Type,_Lm,M}=Mac,{'(',_Lc}|Toks], Def, From, St) -  when Type =:= atom; Type =:= var -> +scan_define_1([{'(',_Lc}|Toks], Mac, Def, From, St) ->      case catch macro_pars(Toks, []) of -        {ok, {As,Me}} -> +        {ok,{As,_}=MacroDef} ->              Len = length(As), -            case dict:find({atom,M}, St#epp.macs) of -                {ok, Defs} when is_list(Defs) -> -                    %% User defined macros: can be overloaded -                    case proplists:is_defined(Len, Defs) of -                        true -> -                            epp_reply(From,{error,{loc(Mac),epp,{redefine,M}}}), -                            wait_req_scan(St); -                        false -> -                            scan_define_cont(From, St, {atom, M}, -                                             {Len, {As, Me}}) -                    end; -                {ok, _PreDef} -> -                    %% Predefined macros: cannot be overloaded -                    %% (There are currently no predefined F(...) macros.) -                    epp_reply(From, {error,{loc(Mac),epp,{redefine_predef,M}}}), -                    wait_req_scan(St); -                error -> -                    scan_define_cont(From, St, {atom, M}, {Len, {As, Me}}) -            end; +	    scan_define_2(Len, MacroDef, Mac, From, St);  	{error,ErrL,What} ->              epp_reply(From, {error,{ErrL,epp,What}}),              wait_req_scan(St); @@ -888,10 +835,29 @@ scan_define([{'(',_Lp},{Type,_Lm,M}=Mac,{'(',_Lc}|Toks], Def, From, St)              epp_reply(From, {error,{loc(Def),epp,{bad,define}}}),              wait_req_scan(St)      end; -scan_define(_Toks, Def, From, St) -> +scan_define_1(_Toks, _Mac, Def, From, St) ->      epp_reply(From, {error,{loc(Def),epp,{bad,define}}}),      wait_req_scan(St). +scan_define_2(Arity, Def, {_,_,Key}=Mac, From, #epp{macs=Ms}=St) -> +    case Ms of +	#{Key:=Defs} when is_list(Defs) -> +	    %% User defined macros: can be overloaded +	    case proplists:is_defined(Arity, Defs) of +		true -> +		    epp_reply(From, {error,{loc(Mac),epp,{redefine,Key}}}), +		    wait_req_scan(St); +		false -> +		    scan_define_cont(From, St, Key, Defs, Arity, Def) +	    end; +	#{Key:=_} -> +	    %% Predefined macros: cannot be overloaded +	    epp_reply(From, {error,{loc(Mac),epp,{redefine_predef,Key}}}), +	    wait_req_scan(St); +	_ -> +	    scan_define_cont(From, St, Key, [], Arity, Def) +    end. +  %%% Detection of circular macro expansions (which would either keep  %%% the compiler looping forever, or run out of memory):  %%% When a macro is defined, we store the names of other macros it @@ -901,11 +867,17 @@ scan_define(_Toks, Def, From, St) ->  %%% the information from St#epp.uses is traversed, and if a circularity  %%% is detected, an error message is thrown. -scan_define_cont(F, St, M, {Arity, Def}) -> -    Ms = dict:append_list(M, [{Arity, Def}], St#epp.macs), -    try dict:append_list(M, [{Arity, macro_uses(Def)}], St#epp.uses) of +scan_define_cont(F, #epp{macs=Ms0}=St, M, Defs, Arity, Def) -> +    Ms = Ms0#{M=>[{Arity,Def}|Defs]}, +    try macro_uses(Def) of          U -> -            scan_toks(F, St#epp{uses=U, macs=Ms}) +	    Uses0 = St#epp.uses, +	    Val = [{Arity,U}|case Uses0 of +				 #{M:=UseList} -> UseList; +				 _ -> [] +			     end], +	    Uses = Uses0#{M=>Val}, +            scan_toks(F, St#epp{uses=Uses,macs=Ms})      catch          {error, Line, Reason} ->              epp_reply(F, {error,{Line,epp,Reason}}), @@ -923,23 +895,23 @@ macro_ref([{'?', _}, {'?', _} | Rest]) ->  macro_ref([{'?', _}, {atom, _, A}=Atom | Rest]) ->      Lm = loc(Atom),      Arity = count_args(Rest, Lm, A), -    [{{atom, A}, Arity} | macro_ref(Rest)]; +    [{A,Arity} | macro_ref(Rest)];  macro_ref([{'?', _}, {var, _, A}=Var | Rest]) ->      Lm = loc(Var),      Arity = count_args(Rest, Lm, A), -    [{{atom, A}, Arity} | macro_ref(Rest)]; +    [{A,Arity} | macro_ref(Rest)];  macro_ref([_Token | Rest]) ->      macro_ref(Rest).  %% scan_undef(Tokens, UndefToken, From, EppState)  scan_undef([{'(',_Llp},{atom,_Lm,M},{')',_Lrp},{dot,_Ld}], _Undef, From, St) -> -    Macs = dict:erase({atom,M}, St#epp.macs), -    Uses = dict:erase({atom,M}, St#epp.uses), +    Macs = maps:remove(M, St#epp.macs), +    Uses = maps:remove(M, St#epp.uses),      scan_toks(From, St#epp{macs=Macs, uses=Uses});  scan_undef([{'(',_Llp},{var,_Lm,M},{')',_Lrp},{dot,_Ld}], _Undef, From,St) -> -    Macs = dict:erase({atom,M}, St#epp.macs), -    Uses = dict:erase({atom,M}, St#epp.uses), +    Macs = maps:remove(M, St#epp.macs), +    Uses = maps:remove(M, St#epp.uses),      scan_toks(From, St#epp{macs=Macs, uses=Uses});  scan_undef(_Toks, Undef, From, St) ->      epp_reply(From, {error,{loc(Undef),epp,{bad,undef}}}), @@ -1006,17 +978,17 @@ scan_include_lib(_Toks, Inc, From, St) ->  %%  Report a badly formed if[n]def test and then treat as undefined macro.  scan_ifdef([{'(',_Llp},{atom,_Lm,M},{')',_Lrp},{dot,_Ld}], _IfD, From, St) -> -    case dict:find({atom,M}, St#epp.macs) of -	{ok,_Def} -> +    case St#epp.macs of +	#{M:=_Def} ->  	    scan_toks(From, St#epp{istk=[ifdef|St#epp.istk]}); -	error -> +	_ ->  	    skip_toks(From, St, [ifdef])      end;  scan_ifdef([{'(',_Llp},{var,_Lm,M},{')',_Lrp},{dot,_Ld}], _IfD, From, St) -> -    case dict:find({atom,M}, St#epp.macs) of -	{ok,_Def} -> +    case St#epp.macs of +	#{M:=_Def} ->  	    scan_toks(From, St#epp{istk=[ifdef|St#epp.istk]}); -	error -> +	_ ->  	    skip_toks(From, St, [ifdef])      end;  scan_ifdef(_Toks, IfDef, From, St) -> @@ -1024,17 +996,17 @@ scan_ifdef(_Toks, IfDef, From, St) ->      wait_req_skip(St, [ifdef]).  scan_ifndef([{'(',_Llp},{atom,_Lm,M},{')',_Lrp},{dot,_Ld}], _IfnD, From, St) -> -    case dict:find({atom,M}, St#epp.macs) of -	{ok,_Def} -> +    case St#epp.macs of +	#{M:=_Def} ->  	    skip_toks(From, St, [ifndef]); -	error -> +	_ ->  	    scan_toks(From, St#epp{istk=[ifndef|St#epp.istk]})      end;  scan_ifndef([{'(',_Llp},{var,_Lm,M},{')',_Lrp},{dot,_Ld}], _IfnD, From, St) -> -    case dict:find({atom,M}, St#epp.macs) of -	{ok,_Def} -> +    case St#epp.macs of +	#{M:=_Def} ->  	    skip_toks(From, St, [ifndef]); -	error -> +	_ ->  	    scan_toks(From, St#epp{istk=[ifndef|St#epp.istk]})      end;  scan_ifndef(_Toks, IfnDef, From, St) -> @@ -1102,7 +1074,8 @@ scan_file([{'(',_Llp},{string,_Ls,Name},{',',_Lc},{integer,_Li,Ln},{')',_Lrp},             {dot,_Ld}], Tf, From, St) ->      Anno = erl_anno:new(Ln),      enter_file_reply(From, Name, Anno, loc(Tf), generated), -    Ms = dict:store({atom,'FILE'}, {none,[{string,line1(),Name}]}, St#epp.macs), +    Ms0 = St#epp.macs, +    Ms = Ms0#{'FILE':={none,[{string,line1(),Name}]}},      Locf = loc(Tf),      NewLoc = new_location(Ln, St#epp.location, Locf),      Delta = get_line(element(2, Tf))-Ln + St#epp.delta, @@ -1190,40 +1163,42 @@ macro_expansion([], Anno0) -> throw({error,loc(Anno0),premature_end}).  %%  Expand the macros in a list of tokens, making sure that an expansion  %%  gets the same location as the macro call. -expand_macros(Type, MacT, M, Toks, Ms0) -> -    %% (Type will always be 'atom') -    {Ms, U} = Ms0, +expand_macros(MacT, M, Toks, Ms0) -> +    {Ms,U} = Ms0,      Lm = loc(MacT),      Tinfo = element(2, MacT), -    case expand_macro1(Type, Lm, M, Toks, Ms) of +    case expand_macro1(Lm, M, Toks, Ms) of  	{ok,{none,Exp}} -> -	    check_uses([{{Type,M}, none}], [], U, Lm), -	    Toks1 = expand_macros(expand_macro(Exp, Tinfo, [], dict:new()), Ms0), +	    check_uses([{M,none}], [], U, Lm), +	    Toks1 = expand_macros(expand_macro(Exp, Tinfo, [], #{}), Ms0),  	    expand_macros(Toks1++Toks, Ms0);  	{ok,{As,Exp}} -> -	    check_uses([{{Type,M}, length(As)}], [], U, Lm), -	    {Bs,Toks1} = bind_args(Toks, Lm, M, As, dict:new()), +	    check_uses([{M,length(As)}], [], U, Lm), +	    {Bs,Toks1} = bind_args(Toks, Lm, M, As, #{}),  	    expand_macros(expand_macro(Exp, Tinfo, Toks1, Bs), Ms0)      end. -expand_macro1(Type, Lm, M, Toks, Ms) -> +expand_macro1(Lm, M, Toks, Ms) ->      Arity = count_args(Toks, Lm, M), -    case dict:find({Type,M}, Ms) of -        error -> %% macro not found -            throw({error,Lm,{undefined,M,Arity}}); -        {ok, undefined} -> %% Predefined macro without definition +    case Ms of +	#{M:=undefined} -> +	    %% Predefined macro without definition.              throw({error,Lm,{undefined,M,Arity}}); -        {ok, [{none, Def}]} -> -            {ok, Def}; -        {ok, Defs} when is_list(Defs) -> -            case proplists:get_value(Arity, Defs) of +	#{M:=[{none,Def}]} -> +            {ok,Def}; +	#{M:=Defs} when is_list(Defs) -> +	    case proplists:get_value(Arity, Defs) of                  undefined ->                      throw({error,Lm,{mismatch,M}});                  Def -> -                    {ok, Def} +                    {ok,Def}              end; -        {ok, PreDef} -> %% Predefined macro -            {ok, PreDef} +        #{M:=PreDef} -> +	    %% Predefined macro. +            {ok,PreDef}; +        _ -> +	    %% Macro not found. +            throw({error,Lm,{undefined,M,Arity}})      end.  check_uses([], _Anc, _U, _Lm) -> @@ -1231,7 +1206,7 @@ check_uses([], _Anc, _U, _Lm) ->  check_uses([M|Rest], Anc, U, Lm) ->      case lists:member(M, Anc) of  	true -> -	    {{_, Name},Arity} = M, +	    {Name,Arity} = M,  	    throw({error,Lm,{circular,Name,Arity}});  	false ->  	    L = get_macro_uses(M, U), @@ -1240,23 +1215,23 @@ check_uses([M|Rest], Anc, U, Lm) ->      end.  get_macro_uses({M,Arity}, U) -> -    case dict:find(M, U) of -	error -> -	    []; -	{ok, L} -> -	    proplists:get_value(Arity, L, proplists:get_value(none, L, [])) +    case U of +	#{M:=L} -> +	    proplists:get_value(Arity, L, proplists:get_value(none, L, [])); +	_ -> +	    []      end.  %% Macro expansion  %% Note: io:scan_erl_form() does not return comments or white spaces.  expand_macros([{'?',_Lq},{atom,_Lm,M}=MacT|Toks], Ms) -> -    expand_macros(atom, MacT, M, Toks, Ms); +    expand_macros(MacT, M, Toks, Ms);  %% Special macros  expand_macros([{'?',_Lq},{var,Lm,'LINE'}=Tok|Toks], Ms) ->      Line = erl_scan:line(Tok),      [{integer,Lm,Line}|expand_macros(Toks, Ms)];  expand_macros([{'?',_Lq},{var,_Lm,M}=MacT|Toks], Ms) -> -    expand_macros(atom, MacT, M, Toks, Ms); +    expand_macros(MacT, M, Toks, Ms);  %% Illegal macros  expand_macros([{'?',_Lq},Token|_Toks], _Ms) ->      T = case erl_scan:text(Token) of @@ -1295,7 +1270,7 @@ macro_args(_Toks, Lm, M, _As, _Bs) ->  store_arg(L, M, _A, [], _Bs) ->      throw({error,L,{mismatch,M}});  store_arg(_L, _M, A, Arg, Bs) -> -    dict:store(A, Arg, Bs). +    Bs#{A=>Arg}.  %% count_args(Tokens, MacroLine, MacroName)  %%  Count the number of arguments in a macro call. @@ -1368,19 +1343,17 @@ macro_arg([], _E, Arg) ->  %%  and then the macro arguments, i.e. simulate textual expansion.  expand_macro([{var,_Lv,V}|Ts], L, Rest, Bs) -> -    case dict:find(V, Bs) of -	{ok,Val} -> -	    %% lists:append(Val, expand_macro(Ts, L, Rest, Bs)); +    case Bs of +	#{V:=Val} ->  	    expand_arg(Val, Ts, L, Rest, Bs); -	error -> +	_ ->  	    [{var,L,V}|expand_macro(Ts, L, Rest, Bs)]      end;  expand_macro([{'?', _}, {'?', _}, {var,_Lv,V}|Ts], L, Rest, Bs) -> -    case dict:find(V, Bs) of -	{ok,Val} -> -	    %% lists:append(Val, expand_macro(Ts, L, Rest, Bs)); +    case Bs of +	#{V:=Val} ->              expand_arg(stringify(Val, L), Ts, L, Rest, Bs); -	error -> +	_ ->  	    [{var,L,V}|expand_macro(Ts, L, Rest, Bs)]      end;  expand_macro([T|Ts], L, Rest, Bs) -> diff --git a/lib/stdlib/src/erl_anno.erl b/lib/stdlib/src/erl_anno.erl index 143318aa55..d32c34dabd 100644 --- a/lib/stdlib/src/erl_anno.erl +++ b/lib/stdlib/src/erl_anno.erl @@ -33,7 +33,7 @@  -export_type([anno_term/0]). --define(LN(L), is_integer(L)). +-define(LN(L), is_integer(L), L >= 0).  -define(COL(C), (is_integer(C) andalso C >= 1)).  %% Location. @@ -52,13 +52,13 @@                      | {'record', record()}                      | {'text', string()}. --type anno() :: location() | [annotation(), ...]. +-opaque anno() :: location() | [annotation(), ...].  -type anno_term() :: term().  -type column() :: pos_integer().  -type generated() :: boolean().  -type filename() :: file:filename_all(). --type line() :: integer(). +-type line() :: non_neg_integer().  -type location() :: line() | {line(), column()}.  -type record() :: boolean().  -type text() :: string(). @@ -90,9 +90,13 @@ to_term(Anno) ->  -ifdef(DEBUG).  from_term(Term) when is_list(Term) ->      Term; +from_term(Line) when is_integer(Line), Line < 0 -> % Before OTP 19 +    set_generated(true, new(-Line));  from_term(Term) ->      [{location, Term}].  -else. +from_term(Line) when is_integer(Line), Line < 0 -> % Before OTP 19 +    set_generated(true, new(-Line));  from_term(Term) ->      Term.  -endif. @@ -198,18 +202,11 @@ file(Anno) ->        Anno :: anno().  generated(Line) when ?ALINE(Line) -> -    Line =< 0; +    false;  generated({Line, Column}) when ?ALINE(Line), ?ACOLUMN(Column) -> -    Line =< 0; +    false;  generated(Anno) -> -    _ = anno_info(Anno, generated, false), -    {location, Location} = lists:keyfind(location, 1, Anno), -    case Location of -        {Line, _Column} -> -            Line =< 0; -        Line -> -            Line =< 0 -    end. +    anno_info(Anno, generated, false).  -spec line(Anno) -> line() when        Anno :: anno(). @@ -226,18 +223,11 @@ line(Anno) ->        Anno :: anno().  location(Line) when ?ALINE(Line) -> -    abs(Line); -location({Line, Column}) when ?ALINE(Line), ?ACOLUMN(Column) -> -    {abs(Line), Column}; +    Line; +location({Line, Column}=Location) when ?ALINE(Line), ?ACOLUMN(Column) -> +    Location;  location(Anno) -> -    case anno_info(Anno, location) of -        Line when Line < 0 -> -            -Line; -        {Line, Column} when Line < 0 -> -            {-Line, Column}; -        Location -> -            Location -    end. +    anno_info(Anno, location).  -spec record(Anno) -> record() when        Anno :: anno(). @@ -270,31 +260,8 @@ set_file(File, Anno) ->        Generated :: generated(),        Anno :: anno(). -set_generated(true, Line) when ?ALINE(Line) -> -    -abs(Line); -set_generated(false, Line) when ?ALINE(Line) -> -    abs(Line); -set_generated(true, {Line, Column}) when ?ALINE(Line), -                                         ?ACOLUMN(Column) -> -    {-abs(Line),Column}; -set_generated(false, {Line, Column}) when ?ALINE(Line), -                                          ?ACOLUMN(Column) -> -    {abs(Line),Column};  set_generated(Generated, Anno) -> -    _ = set(generated, Generated, Anno), -    {location, Location} = lists:keyfind(location, 1, Anno), -    NewLocation = -        case Location of -            {Line, Column} when Generated -> -                {-abs(Line), Column}; -            {Line, Column} when not Generated -> -                {abs(Line), Column}; -            Line when Generated -> -                -abs(Line); -            Line when not Generated -> -                abs(Line) -        end, -    lists:keyreplace(location, 1, Anno, {location, NewLocation}). +    set(generated, Generated, Anno).  -spec set_line(Line, Anno) -> Anno when        Line :: line(), @@ -313,38 +280,17 @@ set_line(Line, Anno) ->        Anno :: anno().  set_location(Line, L) when ?ALINE(L), ?LLINE(Line) -> -    new_location(fix_line(Line, L)); +    new_location(Line);  set_location(Line, {L, Column}) when ?ALINE(L), ?ACOLUMN(Column),                                       ?LLINE(Line) -> -    new_location(fix_line(Line, L)); +    new_location(Line);  set_location({L, C}=Loc, Line) when ?ALINE(Line), ?LLINE(L), ?LCOLUMN(C) -> -    new_location(fix_location(Loc, Line)); +    new_location(Loc);  set_location({L, C}=Loc, {Line, Column}) when ?ALINE(Line), ?ACOLUMN(Column),                                                ?LLINE(L), ?LCOLUMN(C) -> -    new_location(fix_location(Loc, Line)); +    new_location(Loc);  set_location(Location, Anno) -> -    _ = set(location, Location, Anno), -    {location, OldLocation} = lists:keyfind(location, 1, Anno), -    NewLocation = -        case {Location, OldLocation} of -            {{_Line, _Column}=Loc, {L, _C}} -> -                fix_location(Loc, L); -            {Line, {L, _C}} -> -                fix_line(Line, L); -            {{_Line, _Column}=Loc, L} -> -                fix_location(Loc, L); -            {Line, L} -> -                fix_line(Line, L) -        end, -    lists:keyreplace(location, 1, Anno, {location, NewLocation}). - -fix_location({Line, Column}, OldLine) -> -    {fix_line(Line, OldLine), Column}. - -fix_line(Line, OldLine) when OldLine < 0, Line > 0 -> -    -Line; -fix_line(Line, _OldLine) -> -    Line. +    set(location, Location, Anno).  -spec set_record(Record, Anno) -> Anno when        Record :: record(), @@ -383,7 +329,7 @@ set_anno(Item, Value, Anno) ->                      _ ->                          lists:keyreplace(Item, 1, Anno, {Item, Value})                  end, -            simplify(R) +            reset_simplify(R)      end.  reset(Anno, Item) -> diff --git a/lib/stdlib/src/erl_lint.erl b/lib/stdlib/src/erl_lint.erl index 5678e7eebe..3ce6abe752 100644 --- a/lib/stdlib/src/erl_lint.erl +++ b/lib/stdlib/src/erl_lint.erl @@ -31,12 +31,8 @@  -export([is_guard_expr/1]).  -export([bool_option/4,value_option/3,value_option/7]). --export([modify_line/2]). -  -import(lists, [member/2,map/2,foldl/3,foldr/3,mapfoldl/3,all/2,reverse/1]). --deprecated([{modify_line, 2, next_major_release}]). -  %% bool_option(OnOpt, OffOpt, Default, Options) -> boolean().  %% value_option(Flag, Default, Options) -> Value.  %% value_option(Flag, Default, OnOpt, OnVal, OffOpt, OffVal, Options) -> @@ -79,7 +75,7 @@ value_option(Flag, Default, On, OnVal, Off, OffVal, Opts) ->  %%-define(DEBUGF(X,Y), io:format(X, Y)).  -define(DEBUGF(X,Y), void). --type line() :: erl_anno:line().     % a convenient alias +-type line() :: erl_anno:anno().     % a convenient alias  -type fa()   :: {atom(), arity()}.   % function+arity  -type ta()   :: {atom(), arity()}.   % type+arity @@ -238,6 +234,9 @@ format_error({removed, MFA, ReplacementMFA, Rel}) ->  		  "use ~s", [format_mfa(MFA), Rel, format_mfa(ReplacementMFA)]);  format_error({removed, MFA, String}) when is_list(String) ->      io_lib:format("~s: ~s", [format_mfa(MFA), String]); +format_error({removed_type, MNA, ReplacementMNA, Rel}) -> +    io_lib:format("the type ~s was removed in ~s; use ~s instead", +                  [format_mna(MNA), Rel, format_mna(ReplacementMNA)]);  format_error({obsolete_guard, {F, A}}) ->      io_lib:format("~p/~p obsolete", [F, A]);  format_error({too_many_arguments,Arity}) -> @@ -374,9 +373,9 @@ format_error({spec_fun_undefined, {F, A}}) ->  format_error({missing_spec, {F,A}}) ->      io_lib:format("missing specification for function ~w/~w", [F, A]);  format_error(spec_wrong_arity) -> -    "spec has the wrong arity"; +    "spec has wrong arity";  format_error(callback_wrong_arity) -> -    "callback has the wrong arity"; +    "callback has wrong arity";  format_error({deprecated_builtin_type, {Name, Arity},                Replacement, Rel}) ->      UseS = case Replacement of @@ -416,6 +415,9 @@ format_mfa({M, F, A}) when is_integer(A) ->  format_mf(M, F, ArityString) when is_atom(M), is_atom(F) ->      atom_to_list(M) ++ ":" ++ atom_to_list(F) ++ "/" ++ ArityString. +format_mna({M, N, A}) when is_integer(A) -> +    atom_to_list(M) ++ ":" ++ atom_to_list(N) ++ gen_type_paren(A). +  format_where(L) when is_integer(L) ->      io_lib:format("(line ~p)", [L]);  format_where({L,C}) when is_integer(L), is_integer(C) -> @@ -2876,7 +2878,7 @@ spec_decl(Line, MFA0, TypeSpecs, St0 = #lint{specs = Specs, module = Mod}) ->      St1 = St0#lint{specs = dict:store(MFA, Line, Specs)},      case dict:is_key(MFA, Specs) of  	true -> add_error(Line, {redefine_spec, MFA0}, St1); -	false -> check_specs(TypeSpecs, Arity, St1) +	false -> check_specs(TypeSpecs, spec_wrong_arity, Arity, St1)      end.  %% callback_decl(Line, Fun, Types, State) -> State. @@ -2890,7 +2892,8 @@ callback_decl(Line, MFA0, TypeSpecs,              St1 = St0#lint{callbacks = dict:store(MFA, Line, Callbacks)},              case dict:is_key(MFA, Callbacks) of                  true -> add_error(Line, {redefine_callback, MFA0}, St1); -                false -> check_specs(TypeSpecs, Arity, St1) +                false -> check_specs(TypeSpecs, callback_wrong_arity, +                                     Arity, St1)              end      end. @@ -2927,7 +2930,7 @@ is_fa({FuncName, Arity})    when is_atom(FuncName), is_integer(Arity), Arity >= 0 -> true;  is_fa(_) -> false. -check_specs([FunType|Left], Arity, St0) -> +check_specs([FunType|Left], ETag, Arity, St0) ->      {FunType1, CTypes} =  	case FunType of  	    {type, _, bounded_fun, [FT = {type, _, 'fun', _}, Cs]} -> @@ -2935,18 +2938,16 @@ check_specs([FunType|Left], Arity, St0) ->  		{FT, lists:append(Types0)};  	    {type, _, 'fun', _} = FT -> {FT, []}  	end, -    SpecArity = -	case FunType1 of -	    {type, L, 'fun', [any, _]} -> any; -	    {type, L, 'fun', [{type, _, product, D}, _]} -> length(D) -	end, +    {type, L, 'fun', [{type, _, product, D}, _]} = FunType1, +    SpecArity = length(D),      St1 = case Arity =:= SpecArity of  	      true -> St0; -	      false -> add_error(L, spec_wrong_arity, St0) +	      false -> %% Cannot happen if called from the compiler. +                  add_error(L, ETag, St0)  	  end,      St2 = check_type({type, nowarn(), product, [FunType1|CTypes]}, St1), -    check_specs(Left, Arity, St2); -check_specs([], _Arity, St) -> +    check_specs(Left, ETag, Arity, St2); +check_specs([], _ETag, _Arity, St) ->      St.  nowarn() -> @@ -3190,8 +3191,8 @@ handle_generator(P,E,Vt,Uvt,St0) ->  handle_bitstring_gen_pat({bin,_,Segments=[_|_]},St) ->      case lists:last(Segments) of          {bin_element,Line,{var,_,_},default,Flags} when is_list(Flags) -> -            case member(binary, Flags) orelse member(bits, Flags) -                                       orelse member(bitstring, Flags) of +            case member(binary, Flags) orelse member(bytes, Flags) +              orelse member(bits, Flags) orelse member(bitstring, Flags) of                  true ->                      add_error(Line, unsized_binary_in_bin_gen_pattern, St);                  false -> @@ -3485,13 +3486,6 @@ vt_no_unused(Vt) -> [V || {_,{_,U,_L}}=V <- Vt, U =/= unused].  copy_expr(Expr, Anno) ->      erl_parse:map_anno(fun(_A) -> Anno end, Expr). -%% modify_line(Form, Fun) -> Form -%% modify_line(Expression, Fun) -> Expression -%%  Applies Fun to each line number occurrence. - -modify_line(T, F0) -> -    erl_parse:map_anno(F0, T). -  %% Check a record_info call. We have already checked that it is not  %% shadowed by an import. @@ -3560,6 +3554,7 @@ deprecated_function(Line, M, F, As, St) ->  	    St      end. +-dialyzer({no_match, deprecated_type/5}).  deprecated_type(L, M, N, As, St) ->      NAs = length(As),      case otp_internal:obsolete_type(M, N, NAs) of @@ -3570,6 +3565,8 @@ deprecated_type(L, M, N, As, St) ->                  false ->                      St              end; +        {removed, Replacement, Rel} -> +            add_warning(L, {removed_type, {M,N,NAs}, Replacement, Rel}, St);          no ->              St      end. diff --git a/lib/stdlib/src/erl_parse.yrl b/lib/stdlib/src/erl_parse.yrl index e82282421e..e07ab2efc2 100644 --- a/lib/stdlib/src/erl_parse.yrl +++ b/lib/stdlib/src/erl_parse.yrl @@ -85,10 +85,6 @@ type_spec -> '(' spec_fun type_sigs ')' : {'$2', '$3'}.  spec_fun ->                           atom : '$1'.  spec_fun ->                  atom ':' atom : {'$1', '$3'}. -%% The following two are retained only for backwards compatibility; -%% they are not part of the EEP syntax and should be removed. -spec_fun ->          atom '/' integer '::' : {'$1', '$3'}. -spec_fun -> atom ':' atom '/' integer '::' : {'$1', '$3', '$5'}.  typed_attr_val -> expr ',' typed_record_fields : {typed_record, '$1', '$3'}.  typed_attr_val -> expr '::' top_type           : {type_def, '$1', '$3'}. @@ -525,11 +521,6 @@ Erlang code.  -export([type_inop_prec/1,type_preop_prec/1]).  -export([map_anno/2, fold_anno/3, mapfold_anno/3,           new_anno/1, anno_to_term/1, anno_from_term/1]). --export([set_line/2,get_attribute/2,get_attributes/1]). - --deprecated([{set_line, 2, next_major_release}, -             {get_attribute, 2, next_major_release}, -             {get_attributes, 1, next_major_release}]).  %% The following directive is needed for (significantly) faster compilation  %% of the generated .erl file by the HiPE compiler.  Please do not remove. @@ -639,14 +630,8 @@ build_type_spec({Kind,Aa}, {SpecFun, TypeSpecs})  	    {atom, _, Fun} ->  		{Fun, find_arity_from_specs(TypeSpecs)};  	    {{atom,_, Mod}, {atom,_, Fun}} -> -		{Mod,Fun,find_arity_from_specs(TypeSpecs)}; -	    {{atom, _, Fun}, {integer, _, Arity}} -> -		%% Old style spec. Allow this for now. -		{Fun,Arity}; -	    {{atom,_, Mod}, {atom, _, Fun}, {integer, _, Arity}} -> -		%% Old style spec. Allow this for now. -		{Mod,Fun,Arity} -	    end, +		{Mod,Fun,find_arity_from_specs(TypeSpecs)} +        end,      {attribute,Aa,Kind,{NewSpecFun, TypeSpecs}}.  find_arity_from_specs([Spec|_]) -> @@ -795,31 +780,11 @@ record_fields([{match,_Am,{atom,Aa,A},Expr}|Fields]) ->      [{record_field,Aa,{atom,Aa,A},Expr}|record_fields(Fields)];  record_fields([{typed,Expr,TypeInfo}|Fields]) ->      [Field] = record_fields([Expr]), -    TypeInfo1 = -	case Expr of -	    {match, _, _, _} -> TypeInfo; %% If we have an initializer. -	    {atom, Aa, _} -> -                case has_undefined(TypeInfo) of -                    false -> -                        lift_unions(abstract2(undefined, Aa), TypeInfo); -                    true -> -                        TypeInfo -                end -	end, -    [{typed_record_field,Field,TypeInfo1}|record_fields(Fields)]; +    [{typed_record_field,Field,TypeInfo}|record_fields(Fields)];  record_fields([Other|_Fields]) ->      ret_err(?anno(Other), "bad record field");  record_fields([]) -> []. -has_undefined({atom,_,undefined}) -> -    true; -has_undefined({ann_type,_,[_,T]}) -> -    has_undefined(T); -has_undefined({type,_,union,Ts}) -> -    lists:any(fun has_undefined/1, Ts); -has_undefined(_) -> -    false. -  term(Expr) ->      try normalise(Expr)      catch _:_R -> ret_err(?anno(Expr), "bad attribute") @@ -1118,28 +1083,6 @@ type_preop_prec('-') -> {600,700};  type_preop_prec('bnot') -> {600,700};  type_preop_prec('#') -> {700,800}. -%%% [Experimental]. The parser just copies the attributes of the -%%% scanner tokens to the abstract format. This design decision has -%%% been hidden to some extent: use set_line() and get_attribute() to -%%% access the second element of (almost all) of the abstract format -%%% tuples. A typical use is to negate line numbers to prevent the -%%% compiler from emitting warnings and errors. The second element can -%%% (of course) be set to any value, but then these functions no -%%% longer apply. To get all present attributes as a property list -%%% get_attributes() should be used. - --compile({nowarn_deprecated_function,{erl_scan,set_attribute,3}}). -set_line(L, F) -> -    erl_scan:set_attribute(line, L, F). - --compile({nowarn_deprecated_function,{erl_scan,attributes_info,2}}). -get_attribute(L, Name) -> -    erl_scan:attributes_info(L, Name). - --compile({nowarn_deprecated_function,{erl_scan,attributes_info,1}}). -get_attributes(L) -> -    erl_scan:attributes_info(L). -  -spec map_anno(Fun, Abstr) -> NewAbstr when        Fun :: fun((Anno) -> Anno),        Anno :: erl_anno:anno(), diff --git a/lib/stdlib/src/erl_scan.erl b/lib/stdlib/src/erl_scan.erl index d2f53816b8..47223b129c 100644 --- a/lib/stdlib/src/erl_scan.erl +++ b/lib/stdlib/src/erl_scan.erl @@ -52,25 +52,15 @@  %%% External exports  -export([string/1,string/2,string/3,tokens/3,tokens/4, -         format_error/1,reserved_word/1, -         token_info/1,token_info/2, -         attributes_info/1,attributes_info/2,set_attribute/3]). +         format_error/1,reserved_word/1]).  -export([column/1,end_location/1,line/1,location/1,text/1,           category/1,symbol/1]). --deprecated([{attributes_info, 1, next_major_release}, -             {attributes_info, 2, next_major_release}, -             {set_attribute, 3, next_major_release}, -             {token_info, 1, next_major_release}, -             {token_info, 2, next_major_release}]). -  %%% Private  -export([continuation_location/1]).  -export_type([error_info/0, -              line/0, -              location/0,                options/0,                return_cont/0,                token/0, @@ -85,29 +75,18 @@  -define(ALINE(L), is_integer(L)).  -define(STRING(S), is_list(S)).  -define(RESWORDFUN(F), is_function(F, 1)). --define(SETATTRFUN(F), is_function(F, 1)).  -type category() :: atom(). --type column() :: pos_integer().                % Deprecated --type line() :: integer().                      % Deprecated --type location() :: line() | {line(),column()}. % Deprecated  -type resword_fun() :: fun((atom()) -> boolean()).  -type option() :: 'return' | 'return_white_spaces' | 'return_comments'                  | 'text' | {'reserved_word_fun', resword_fun()}.  -type options() :: option() | [option()].  -type symbol() :: atom() | float() | integer() | string(). --type info_line() :: integer() | term(). --type attributes_data() -       :: [{'column', column()} | {'line', info_line()} | {'text', string()}] -        |  {line(), column()}. -%% The fact that {line(),column()} is a possible attributes() type -%% is hidden. --type attributes() :: line() | attributes_data(). --type token() :: {category(), attributes(), symbol()} -               | {category(), attributes()}. +-type token() :: {category(), Anno :: erl_anno:anno(), symbol()} +               | {category(), Anno :: erl_anno:anno()}.  -type tokens() :: [token()].  -type error_description() :: term(). --type error_info() :: {location(), module(), error_description()}. +-type error_info() :: {erl_anno:location(), module(), error_description()}.  %%% Local record.  -record(erl_scan, @@ -136,8 +115,8 @@ format_error(Other) ->        String :: string(),        Return :: {'ok', Tokens :: tokens(), EndLocation}                | {'error', ErrorInfo :: error_info(), ErrorLocation}, -      EndLocation :: location(), -      ErrorLocation :: location(). +      EndLocation :: erl_anno:location(), +      ErrorLocation :: erl_anno:location().  string(String) ->      string(String, 1, []). @@ -145,9 +124,9 @@ string(String) ->        String :: string(),        Return :: {'ok', Tokens :: tokens(), EndLocation}                | {'error', ErrorInfo :: error_info(), ErrorLocation}, -      StartLocation :: location(), -      EndLocation :: location(), -      ErrorLocation :: location(). +      StartLocation :: erl_anno:location(), +      EndLocation :: erl_anno:location(), +      ErrorLocation :: erl_anno:location().  string(String, StartLocation) ->      string(String, StartLocation, []). @@ -156,9 +135,9 @@ string(String, StartLocation) ->        Options :: options(),        Return :: {'ok', Tokens :: tokens(), EndLocation}                | {'error', ErrorInfo :: error_info(), ErrorLocation}, -      StartLocation :: location(), -      EndLocation :: location(), -      ErrorLocation :: location(). +      StartLocation :: erl_anno:location(), +      EndLocation :: erl_anno:location(), +      ErrorLocation :: erl_anno:location().  string(String, Line, Options) when ?STRING(String), ?ALINE(Line) ->      string1(String, options(Options), Line, no_col, []);  string(String, {Line,Column}, Options) when ?STRING(String), @@ -167,20 +146,23 @@ string(String, {Line,Column}, Options) when ?STRING(String),      string1(String, options(Options), Line, Column, []).  -type char_spec() :: string() | 'eof'. --type cont_fun() :: fun((char_spec(), #erl_scan{}, line(), column(), +-type cont_fun() :: fun((char_spec(), #erl_scan{}, +                         erl_anno:line(), erl_anno:column(),                           tokens(), any()) -> any()).  -opaque return_cont() :: {erl_scan_continuation, -                          string(), column(), tokens(), line(), +                          string(), erl_anno:column(), tokens(), +                          erl_anno:line(),                            #erl_scan{}, any(), cont_fun()}. --type tokens_result() :: {'ok', Tokens :: tokens(), EndLocation :: location()} -                       | {'eof', EndLocation :: location()} +-type tokens_result() :: {'ok', Tokens :: tokens(), +                          EndLocation :: erl_anno:location()} +                       | {'eof', EndLocation :: erl_anno:location()}                         | {'error', ErrorInfo :: error_info(), -                          EndLocation :: location()}. +                          EndLocation :: erl_anno:location()}.  -spec tokens(Continuation, CharSpec, StartLocation) -> Return when        Continuation :: return_cont() | [],        CharSpec :: char_spec(), -      StartLocation :: location(), +      StartLocation :: erl_anno:location(),        Return :: {'done',Result :: tokens_result(),LeftOverChars :: char_spec()}                | {'more', Continuation1 :: return_cont()}.  tokens(Cont, CharSpec, StartLocation) -> @@ -189,7 +171,7 @@ tokens(Cont, CharSpec, StartLocation) ->  -spec tokens(Continuation, CharSpec, StartLocation, Options) -> Return when        Continuation :: return_cont() | [],        CharSpec :: char_spec(), -      StartLocation :: location(), +      StartLocation :: erl_anno:location(),        Options :: options(),        Return :: {'done',Result :: tokens_result(),LeftOverChars :: char_spec()}                | {'more', Continuation1 :: return_cont()}. @@ -257,155 +239,6 @@ symbol({_Category,_Anno,Symbol}) ->  symbol(T) ->      erlang:error(badarg, [T]). --type attribute_item() :: 'column' | 'length' | 'line' -                        | 'location' | 'text'. --type info_location() :: location() | term(). --type attribute_info() :: {'column', column()}| {'length', pos_integer()} -                        | {'line', info_line()} -                        | {'location', info_location()} -                        | {'text', string()}. --type token_item() :: 'category' | 'symbol' | attribute_item(). --type token_info() :: {'category', category()} | {'symbol', symbol()} -                    | attribute_info(). - --spec token_info(Token) -> TokenInfo when -      Token :: token(), -      TokenInfo :: [TokenInfoTuple :: token_info()]. -token_info(Token) -> -    Items = [category,column,length,line,symbol,text], % undefined order -    token_info(Token, Items). - --spec token_info(Token, TokenItem) -> TokenInfoTuple | 'undefined' when -                     Token :: token(), -                     TokenItem :: token_item(), -                     TokenInfoTuple :: token_info(); -                (Token, TokenItems) -> TokenInfo when -                     Token :: token(), -                     TokenItems :: [TokenItem :: token_item()], -                     TokenInfo :: [TokenInfoTuple :: token_info()]. -token_info(_Token, []) -> -    []; -token_info(Token, [Item|Items]) when is_atom(Item) -> -    case token_info(Token, Item) of -        undefined -> -            token_info(Token, Items); -        TokenInfo when is_tuple(TokenInfo) -> -            [TokenInfo|token_info(Token, Items)] -    end; -token_info({Category,_Attrs}, category=Item) -> -    {Item,Category}; -token_info({Category,_Attrs,_Symbol}, category=Item) -> -    {Item,Category}; -token_info({Category,_Attrs}, symbol=Item) -> -    {Item,Category}; -token_info({_Category,_Attrs,Symbol}, symbol=Item) -> -    {Item,Symbol}; -token_info({_Category,Attrs}, Item) -> -    attributes_info(Attrs, Item); -token_info({_Category,Attrs,_Symbol}, Item) -> -    attributes_info(Attrs, Item). - --spec attributes_info(Attributes) -> AttributesInfo when -      Attributes :: attributes(), -      AttributesInfo :: [AttributeInfoTuple :: attribute_info()]. -attributes_info(Attributes) -> -    Items = [column,length,line,text], % undefined order -    attributes_info(Attributes, Items). - --spec attributes_info -        (Attributes, AttributeItem) -> AttributeInfoTuple | 'undefined' when -             Attributes :: attributes(), -             AttributeItem :: attribute_item(), -             AttributeInfoTuple :: attribute_info(); -        (Attributes, AttributeItems) -> AttributeInfo when -             Attributes :: attributes(), -             AttributeItems :: [AttributeItem :: attribute_item()], -             AttributeInfo :: [AttributeInfoTuple :: attribute_info()]. -attributes_info(_Attrs, []) -> -    []; -attributes_info(Attrs, [A|As]) when is_atom(A) -> -    case attributes_info(Attrs, A) of -        undefined -> -            attributes_info(Attrs, As); -        AttributeInfo when is_tuple(AttributeInfo) -> -            [AttributeInfo|attributes_info(Attrs, As)] -    end; -attributes_info({Line,Column}, column=Item) when ?ALINE(Line), -                                                 ?COLUMN(Column) -> -    {Item,Column}; -attributes_info(Line, column) when ?ALINE(Line) -> -    undefined; -attributes_info(Attrs, column=Item) -> -    case attr_info(Attrs, Item) of -        undefined -> -            case erl_anno:column(Attrs) of -                undefined -> -                    undefined; -                Column -> -                    {Item,Column} -            end; -        T -> -            T -    end; -attributes_info(Attrs, length=Item) -> -    case attributes_info(Attrs, text) of -        undefined -> -            undefined; -        {text,Text} -> -            {Item,length(Text)} -    end; -attributes_info(Line, line=Item) when ?ALINE(Line) -> -    {Item,Line}; -attributes_info({Line,Column}, line=Item) when ?ALINE(Line), -                                               ?COLUMN(Column) -> -    {Item,Line}; -attributes_info(Attrs, line=Item) -> -    case attr_info(Attrs, Item) of -        undefined -> -            case attr_info(Attrs, location) of -                {location,{Line,_Column}} -> -                    {Item,Line}; -                {location,Line} -> -                    {Item,Line}; -                undefined -> -                    undefined -            end; -        T -> -            T -    end; -attributes_info({Line,Column}=Location, location=Item) when ?ALINE(Line), -                                                            ?COLUMN(Column) -> -    {Item,Location}; -attributes_info(Line, location=Item) when ?ALINE(Line) -> -    {Item,Line}; -attributes_info(Attrs, location=Item) -> -    {line,Line} = attributes_info(Attrs, line), -    case attributes_info(Attrs, column) of -        undefined -> -            %% If set_attribute() has assigned a term such as {17,42} -            %% to 'line', then Line will look like {Line,Column}. One -            %% should not use 'location' but 'line' and 'column' in -            %% such special cases. -            {Item,Line}; -        {column,Column} -> -            {Item,{Line,Column}} -    end; -attributes_info({Line,Column}, text) when ?ALINE(Line), ?COLUMN(Column) -> -    undefined; -attributes_info(Line, text) when ?ALINE(Line) -> -    undefined; -attributes_info(Attrs, text=Item) -> -    attr_info(Attrs, Item); -attributes_info(T1, T2) -> -    erlang:error(badarg, [T1,T2]). - --spec set_attribute(AttributeItem, Attributes, SetAttributeFun) -> Attributes when -      AttributeItem :: 'line', -      Attributes :: attributes(), -      SetAttributeFun :: fun((info_line()) -> info_line()). -set_attribute(Tag, Attributes, Fun) when ?SETATTRFUN(Fun) -> -    set_attr(Tag, Attributes, Fun). -  %%%  %%% Local functions  %%% @@ -471,62 +304,6 @@ expand_opt(return, Os) ->  expand_opt(O, Os) ->      [O|Os]. -attr_info(Attrs, Item) -> -    try lists:keyfind(Item, 1, Attrs) of -        {_Item, _Value} = T -> -            T; -        false -> -            undefined -    catch -	_:_ -> -            erlang:error(badarg, [Attrs, Item]) -    end. - --spec set_attr('line', attributes(), fun((line()) -> line())) -> attributes(). - -set_attr(line, Line, Fun) when ?ALINE(Line) -> -    Ln = Fun(Line), -    if -        ?ALINE(Ln) -> -            Ln; -        true -> -            [{line,Ln}] -    end; -set_attr(line, {Line,Column}, Fun) when ?ALINE(Line), ?COLUMN(Column) -> -    Ln = Fun(Line), -    if -        ?ALINE(Ln) -> -            {Ln,Column}; -        true -> -            [{line,Ln},{column,Column}] -    end; -set_attr(line=Tag, Attrs, Fun) when is_list(Attrs) -> -    case lists:keyfind(Tag, 1, Attrs) of -        {line,Line} -> -            case lists:keyreplace(Tag, 1, Attrs, {line,Fun(Line)}) of -                [{line,Ln}] when ?ALINE(Ln) -> -                    Ln; -                As -> -                    As -            end; -        false -> -            {location, Location} = lists:keyfind(location, 1, Attrs), -            Ln = case Location of -                     {Line,Column} when ?ALINE(Line), ?COLUMN(Column) -> -                         {Fun(Line),Column}; -                     _ -> -                         Fun(Location) -                 end, -            case lists:keyreplace(location, 1, Attrs, {location,Ln}) of -                [{location,Ln}] when ?ALINE(Ln) -> -                    Ln; -                As -> -                    As -            end -    end; -set_attr(T1, T2, T3) -> -    erlang:error(badarg, [T1,T2,T3]). -  tokens1(Cs, St, Line, Col, Toks, Fun, Any) when ?STRING(Cs); Cs =:= eof ->      case Fun(Cs, St, Line, Col, Toks, Any) of          {more,{Cs0,Ncol,Ntoks,Nline,Nany,Nfun}} -> diff --git a/lib/stdlib/src/escript.erl b/lib/stdlib/src/escript.erl index 41b49f4a86..b8ce311c35 100644 --- a/lib/stdlib/src/escript.erl +++ b/lib/stdlib/src/escript.erl @@ -38,7 +38,7 @@  -record(state, {file         :: file:filename(),                  module       :: module(),                  forms_or_bin, -                source       :: source(), +                source       :: source() | 'undefined',                  n_errors     :: non_neg_integer(),                  mode         :: mode(),                  exports_main :: boolean(), @@ -49,9 +49,9 @@  -type emu_args() :: string().  -record(sections, {type, -		   shebang  :: shebang(), -		   comment  :: comment(), -		   emu_args :: emu_args(), +		   shebang  :: shebang() | 'undefined', +		   comment  :: comment() | 'undefined', +		   emu_args :: emu_args() | 'undefined',  		   body}).  -record(extract_options, {compile_source}). diff --git a/lib/stdlib/src/io.erl b/lib/stdlib/src/io.erl index 284f2e5a2b..5dc8b4541e 100644 --- a/lib/stdlib/src/io.erl +++ b/lib/stdlib/src/io.erl @@ -631,41 +631,20 @@ io_requests(Pid, [], [Rs|Cont], Tail) ->  io_requests(_Pid, [], [], _Tail) ->       {false,[]}. - -bc_req(Pid,{Op,Enc,Param},MaybeConvert) -> -    case net_kernel:dflag_unicode_io(Pid) of -	true -> -	    {false,{Op,Enc,Param}}; -	false -> -	    {MaybeConvert,{Op,Param}} -    end; -bc_req(Pid,{Op,Enc,P,F},MaybeConvert) -> -    case net_kernel:dflag_unicode_io(Pid) of -	true -> -	    {false,{Op,Enc,P,F}}; -	false -> -	    {MaybeConvert,{Op,P,F}} -    end; -bc_req(Pid, {Op,Enc,M,F,A},MaybeConvert) -> +bc_req(Pid, Req0, MaybeConvert) ->      case net_kernel:dflag_unicode_io(Pid) of  	true -> -	    {false,{Op,Enc,M,F,A}}; +	    %% The most common case. A modern i/o server. +	    {false,Req0};  	false -> -	    {MaybeConvert,{Op,M,F,A}} -    end; -bc_req(Pid, {Op,Enc,P,M,F,A},MaybeConvert) -> -    case net_kernel:dflag_unicode_io(Pid) of -	true -> -	    {false,{Op,Enc,P,M,F,A}}; -	false -> -	    {MaybeConvert,{Op,P,M,F,A}} -    end; -bc_req(Pid,{Op,Enc},MaybeConvert) -> -    case net_kernel:dflag_unicode_io(Pid) of -	true -> -	    {false,{Op, Enc}}; -	false -> -	    {MaybeConvert,Op} +	    %% Backward compatibility only. Unlikely to ever happen. +	    case tuple_to_list(Req0) of +		[Op,_Enc] -> +		    {MaybeConvert,Op}; +		[Op,_Enc|T] -> +		    Req = list_to_tuple([Op|T]), +		    {MaybeConvert,Req} +	    end      end.  io_request(Pid, {write,Term}) -> diff --git a/lib/stdlib/src/otp_internal.erl b/lib/stdlib/src/otp_internal.erl index 2d77888512..960c70f255 100644 --- a/lib/stdlib/src/otp_internal.erl +++ b/lib/stdlib/src/otp_internal.erl @@ -586,49 +586,40 @@ obsolete_1(asn1rt, utf8_list_to_binary, 1) ->  %% Added in OTP 18.  obsolete_1(core_lib, get_anno, 1) -> -    {deprecated,{cerl,get_ann,1}}; +    {removed,{cerl,get_ann,1},"19"};  obsolete_1(core_lib, set_anno, 2) -> -    {deprecated,{cerl,set_ann,2}}; +    {removed,{cerl,set_ann,2},"19"};  obsolete_1(core_lib, is_literal, 1) -> -    {deprecated,{cerl,is_literal,1}}; +    {removed,{cerl,is_literal,1},"19"};  obsolete_1(core_lib, is_literal_list, 1) -> -    {deprecated,"deprecated; use lists:all(fun cerl:is_literal/1, L)" +    {removed,"removed; use lists:all(fun cerl:is_literal/1, L)"       " instead"};  obsolete_1(core_lib, literal_value, 1) -> -    {deprecated,{core_lib,concrete,1}}; +    {removed,{core_lib,concrete,1},"19"};  obsolete_1(erl_scan, set_attribute, 3) -> -    {deprecated, -     "deprecated (will be removed in OTP 19); use erl_anno:set_line/2 instead"}; +    {removed,{erl_anno,set_line,2},"19.0"};  obsolete_1(erl_scan, attributes_info, 1) -> -    {deprecated, -     "deprecated (will be removed in OTP 19); use " +    {removed,"removed in 19.0; use "       "erl_anno:{column,line,location,text}/1 instead"};  obsolete_1(erl_scan, attributes_info, 2) -> -    {deprecated, -     "deprecated (will be removed in OTP 19); use " +    {removed,"removed in 19.0; use "       "erl_anno:{column,line,location,text}/1 instead"};  obsolete_1(erl_scan, token_info, 1) -> -    {deprecated, -     "deprecated (will be removed in OTP 19); use " +    {removed,"removed in 19.0; use "       "erl_scan:{category,column,line,location,symbol,text}/1 instead"};  obsolete_1(erl_scan, token_info, 2) -> -    {deprecated, -     "deprecated (will be removed in OTP 19); use " +    {removed,"removed in 19.0; use "       "erl_scan:{category,column,line,location,symbol,text}/1 instead"};  obsolete_1(erl_parse, set_line, 2) -> -    {deprecated, -     "deprecated (will be removed in OTP 19); use erl_anno:set_line/2 instead"}; +    {removed,{erl_anno,set_line,2},"19.0"};  obsolete_1(erl_parse, get_attributes, 1) -> -    {deprecated, -     "deprecated (will be removed in OTP 19); use " +    {removed,"removed in 19.0; use "       "erl_anno:{column,line,location,text}/1 instead"};  obsolete_1(erl_parse, get_attribute, 2) -> -    {deprecated, -     "deprecated (will be removed in OTP 19); use " +    {removed,"removed in 19.0; use "       "erl_anno:{column,line,location,text}/1 instead"};  obsolete_1(erl_lint, modify_line, 2) -> -    {deprecated, -     "deprecated (will be removed in OTP 19); use erl_parse:map_anno/2 instead"}; +    {removed,{erl_parse,map_anno,2},"19.0"};  obsolete_1(ssl, negotiated_next_protocol, 1) ->      {deprecated,{ssl,negotiated_protocol,1}}; @@ -648,6 +639,14 @@ obsolete_1(httpd_conf, is_file, 1) ->  obsolete_1(httpd_conf, make_integer, 1) ->      {deprecated, "deprecated; use erlang:list_to_integer/1 instead"}; +%% Added in OTP 19. + +obsolete_1(random, _, _) -> +    {deprecated, "the 'random' module is deprecated; " +     "use the 'rand' module instead"}; +obsolete_1(code, rehash, 0) -> +    {deprecated, "deprecated because the code path cache feature has been removed"}; +  obsolete_1(_, _, _) ->      no. @@ -698,26 +697,24 @@ is_snmp_agent_function(_,		      _) -> false.  -spec obsolete_type(module(), atom(), arity()) ->  	'no' | {tag(), string()} | {tag(), mfas(), release()}. +-dialyzer({no_match, obsolete_type/3}).  obsolete_type(Module, Name, NumberOfVariables) ->      case obsolete_type_1(Module, Name, NumberOfVariables) of -%% 	{deprecated=Tag,{_,_,_}=Replacement} -> -%% 	    {Tag,Replacement,"in a future release"}; +	{deprecated=Tag,{_,_,_}=Replacement} -> +	    {Tag,Replacement,"in a future release"};  	{_,String}=Ret when is_list(String) ->  	    Ret; -%% 	{_,_,_}=Ret -> -%% 	    Ret; +	{_,_,_}=Ret -> +	    Ret;  	no ->  	    no      end.  obsolete_type_1(erl_scan,column,0) -> -    {deprecated, -     "deprecated (will be removed in OTP 19); use erl_anno:column() instead"}; +    {removed,{erl_anno,column,0},"19.0"};  obsolete_type_1(erl_scan,line,0) -> -    {deprecated, -     "deprecated (will be removed in OTP 19); use erl_anno:line() instead"}; +    {removed,{erl_anno,line,0},"19.0"};  obsolete_type_1(erl_scan,location,0) -> -    {deprecated, -     "deprecated (will be removed in OTP 19); use erl_anno:location() instead"}; +    {removed,{erl_anno,location,0},"19.0"};  obsolete_type_1(_,_,_) ->      no. diff --git a/lib/stdlib/src/random.erl b/lib/stdlib/src/random.erl index 8b67cde56c..8b639dd0a7 100644 --- a/lib/stdlib/src/random.erl +++ b/lib/stdlib/src/random.erl @@ -18,6 +18,7 @@  %% %CopyrightEnd%  %%  -module(random). +-deprecated(module).  %% Reasonable random number generator.  %%  The method is attributed to B. A. Wichmann and I. D. Hill diff --git a/lib/stdlib/src/slave.erl b/lib/stdlib/src/slave.erl index 24fc8ce204..4e629a5e56 100644 --- a/lib/stdlib/src/slave.erl +++ b/lib/stdlib/src/slave.erl @@ -289,10 +289,7 @@ register_unique_name(Number) ->  %% no need to use rsh.  mk_cmd(Host, Name, Args, Waiter, Prog0) -> -    Prog = case os:type() of -	       {ose,_} -> mk_ose_prog(Prog0); -	       _ -> quote_progname(Prog0) -	   end, +    Prog = quote_progname(Prog0),      BasicCmd = lists:concat([Prog,  			     " -detached -noinput -master ", node(),  			     " ", long_or_short(), Name, "@", Host, @@ -312,24 +309,6 @@ mk_cmd(Host, Name, Args, Waiter, Prog0) ->  	    end      end. -%% On OSE we have to pass the beam arguments directory to the slave -%% process. To find out what arguments that should be passed on we -%% make an assumption. All arguments after the last "--" should be -%% skipped. So given these arguments: -%%     -Muycs256 -A 1 -- -root /mst/ -progname beam.debug.smp -- -home /mst/ -- -kernel inetrc '"/mst/inetrc.conf"' -- -name test@localhost -%% we send -%%     -Muycs256 -A 1 -- -root /mst/ -progname beam.debug.smp -- -home /mst/ -- -kernel inetrc '"/mst/inetrc.conf"' -- -%% to the slave with whatever other args that are added in mk_cmd. -mk_ose_prog(Prog) -> -    SkipTail = fun("--",[]) -> -		       ["--"]; -		  (_,[]) -> -		       []; -		  (Arg,Args) -> -		       [Arg," "|Args] -	       end, -    [Prog,tl(lists:foldr(SkipTail,[],erlang:system_info(emu_args)))]. -  %% This is an attempt to distinguish between spaces in the program  %% path and spaces that separate arguments. The program is quoted to  %% allow spaces in the path. diff --git a/lib/stdlib/src/supervisor.erl b/lib/stdlib/src/supervisor.erl index 92a0c29011..23f3aaee1f 100644 --- a/lib/stdlib/src/supervisor.erl +++ b/lib/stdlib/src/supervisor.erl @@ -1,7 +1,7 @@  %%  %% %CopyrightBegin%  %% -%% Copyright Ericsson AB 1996-2014. All Rights Reserved. +%% Copyright Ericsson AB 1996-2015. All Rights Reserved.  %%  %% Licensed under the Apache License, Version 2.0 (the "License");  %% you may not use this file except in compliance with the License. @@ -107,11 +107,13 @@  -define(SET, sets:set).  -record(state, {name, -		strategy               :: strategy(), +		strategy               :: strategy() | 'undefined',  		children = []          :: [child_rec()], -		dynamics               :: ?DICT(pid(), list()) | ?SET(pid()), -		intensity              :: non_neg_integer(), -		period                 :: pos_integer(), +                dynamics               :: {'dict', ?DICT(pid(), list())} +                                        | {'set', ?SET(pid())} +                                        | 'undefined', +		intensity              :: non_neg_integer() | 'undefined', +		period                 :: pos_integer() | 'undefined',  		restarts = [],  	        module,  	        args}). @@ -577,7 +579,7 @@ handle_cast({try_again_restart,Pid}, #state{children=[Child]}=State)    when ?is_simple(State) ->      RT = Child#child.restart_type,      RPid = restarting(Pid), -    case dynamic_child_args(RPid, dynamics_db(RT, State#state.dynamics)) of +    case dynamic_child_args(RPid, RT, State#state.dynamics) of  	{ok, Args} ->  	    {M, F, _} = Child#child.mfargs,  	    NChild = Child#child{pid = RPid, mfargs = {M, F, Args}}, @@ -735,7 +737,7 @@ handle_start_child(Child, State) ->  restart_child(Pid, Reason, #state{children = [Child]} = State) when ?is_simple(State) ->      RestartType = Child#child.restart_type, -    case dynamic_child_args(Pid, dynamics_db(RestartType, State#state.dynamics)) of +    case dynamic_child_args(Pid, RestartType, State#state.dynamics) of  	{ok, Args} ->  	    {M, F, _} = Child#child.mfargs,  	    NChild = Child#child{pid = Pid, mfargs = {M, F, Args}}, @@ -812,14 +814,16 @@ restart(simple_one_for_one, Child, State) ->  					       State#state.dynamics)),      case do_start_child_i(M, F, A) of  	{ok, Pid} -> -	    NState = State#state{dynamics = ?DICTS:store(Pid, A, Dynamics)}, +            DynamicsDb = {dict, ?DICTS:store(Pid, A, Dynamics)}, +	    NState = State#state{dynamics = DynamicsDb},  	    {ok, NState};  	{ok, Pid, _Extra} -> -	    NState = State#state{dynamics = ?DICTS:store(Pid, A, Dynamics)}, +            DynamicsDb = {dict, ?DICTS:store(Pid, A, Dynamics)}, +	    NState = State#state{dynamics = DynamicsDb},  	    {ok, NState};  	{error, Error} -> -	    NState = State#state{dynamics = ?DICTS:store(restarting(OldPid), A, -							Dynamics)}, +            DynamicsDb = {dict, ?DICTS:store(restarting(OldPid), A, Dynamics)}, +	    NState = State#state{dynamics = DynamicsDb},  	    report_error(start_error, Error, Child, State#state.name),  	    {try_again, NState}      end; @@ -1102,31 +1106,32 @@ save_child(Child, #state{children = Children} = State) ->      State#state{children = [Child |Children]}.  save_dynamic_child(temporary, Pid, _, #state{dynamics = Dynamics} = State) -> -    State#state{dynamics = ?SETS:add_element(Pid, dynamics_db(temporary, Dynamics))}; +    DynamicsDb = dynamics_db(temporary, Dynamics), +    State#state{dynamics = {set, ?SETS:add_element(Pid, DynamicsDb)}};  save_dynamic_child(RestartType, Pid, Args, #state{dynamics = Dynamics} = State) -> -    State#state{dynamics = ?DICTS:store(Pid, Args, dynamics_db(RestartType, Dynamics))}. +    DynamicsDb = dynamics_db(RestartType, Dynamics), +    State#state{dynamics = {dict, ?DICTS:store(Pid, Args, DynamicsDb)}}.  dynamics_db(temporary, undefined) ->      ?SETS:new();  dynamics_db(_, undefined) ->      ?DICTS:new(); -dynamics_db(_,Dynamics) -> -    Dynamics. - -dynamic_child_args(Pid, Dynamics) -> -    case ?SETS:is_set(Dynamics) of -        true -> -            {ok, undefined}; -        false -> -            ?DICTS:find(Pid, Dynamics) -    end. +dynamics_db(_, {_Tag, DynamicsDb}) -> +    DynamicsDb. + +dynamic_child_args(_Pid, temporary, _DynamicsDb) -> +    {ok, undefined}; +dynamic_child_args(Pid, _RT, {dict, DynamicsDb}) -> +    ?DICTS:find(Pid, DynamicsDb); +dynamic_child_args(_Pid, _RT, undefined) -> +    error.  state_del_child(#child{pid = Pid, restart_type = temporary}, State) when ?is_simple(State) ->      NDynamics = ?SETS:del_element(Pid, dynamics_db(temporary, State#state.dynamics)), -    State#state{dynamics = NDynamics}; +    State#state{dynamics = {set, NDynamics}};  state_del_child(#child{pid = Pid, restart_type = RType}, State) when ?is_simple(State) ->      NDynamics = ?DICTS:erase(Pid, dynamics_db(RType, State#state.dynamics)), -    State#state{dynamics = NDynamics}; +    State#state{dynamics = {dict, NDynamics}};  state_del_child(Child, State) ->      NChildren = del_child(Child#child.name, State#state.children),      State#state{children = NChildren}. @@ -1160,19 +1165,19 @@ split_child(_, [], After) ->  get_child(Name, State) ->      get_child(Name, State, false). +  get_child(Pid, State, AllowPid) when AllowPid, is_pid(Pid) ->      get_dynamic_child(Pid, State);  get_child(Name, State, _) ->      lists:keysearch(Name, #child.name, State#state.children).  get_dynamic_child(Pid, #state{children=[Child], dynamics=Dynamics}) -> -    DynamicsDb = dynamics_db(Child#child.restart_type, Dynamics), -    case is_dynamic_pid(Pid, DynamicsDb) of +    case is_dynamic_pid(Pid, Dynamics) of  	true ->  	    {value, Child#child{pid=Pid}};  	false ->  	    RPid = restarting(Pid), -	    case is_dynamic_pid(RPid, DynamicsDb) of +	    case is_dynamic_pid(RPid, Dynamics) of  		true ->  		    {value, Child#child{pid=RPid}};  		false -> @@ -1183,13 +1188,12 @@ get_dynamic_child(Pid, #state{children=[Child], dynamics=Dynamics}) ->  	    end      end. -is_dynamic_pid(Pid, Dynamics) -> -    case ?SETS:is_set(Dynamics) of -	true -> -	    ?SETS:is_element(Pid, Dynamics); -	false -> -	    ?DICTS:is_key(Pid, Dynamics) -    end. +is_dynamic_pid(Pid, {dict, Dynamics}) -> +    ?DICTS:is_key(Pid, Dynamics); +is_dynamic_pid(Pid, {set, Dynamics}) -> +    ?SETS:is_element(Pid, Dynamics); +is_dynamic_pid(_Pid, undefined) -> +    false.  replace_child(Child, State) ->      Chs = do_replace_child(Child, State#state.children), diff --git a/lib/stdlib/test/base64_SUITE.erl b/lib/stdlib/test/base64_SUITE.erl index 75eebba6c6..f750145ef0 100644 --- a/lib/stdlib/test/base64_SUITE.erl +++ b/lib/stdlib/test/base64_SUITE.erl @@ -340,7 +340,7 @@ interleaved_ws_roundtrip_1([], Base64List, Bin, List) ->  random_byte_list(0, Acc) ->      Acc;  random_byte_list(N, Acc) ->  -    random_byte_list(N-1, [random:uniform(255)|Acc]). +    random_byte_list(N-1, [rand:uniform(255)|Acc]).  make_big_binary(N) ->      list_to_binary(mbb(N, [])). diff --git a/lib/stdlib/test/binary_module_SUITE.erl b/lib/stdlib/test/binary_module_SUITE.erl index 70c946bdb9..8a2df2bf85 100644 --- a/lib/stdlib/test/binary_module_SUITE.erl +++ b/lib/stdlib/test/binary_module_SUITE.erl @@ -536,6 +536,12 @@ do_interesting(Module) ->      ?line [<<3>>,<<6>>] = Module:split(<<1,2,3,4,5,6,7,8>>,  					   [<<1>>,<<2>>,<<4>>,<<5>>,<<7>>,<<8>>],  					   [global,trim_all]), +    [<<>>] = binary:split(<<>>, <<",">>, []), +    [] = binary:split(<<>>, <<",">>, [trim]), +    [] = binary:split(<<>>, <<",">>, [trim_all]), +    [] = binary:split(<<>>, <<",">>, [global,trim]), +    [] = binary:split(<<>>, <<",">>, [global,trim_all]), +      ?line badarg = ?MASK_ERROR(  		      Module:replace(<<1,2,3,4,5,6,7,8>>,  				     [<<4,5>>,<<7>>,<<8>>],<<99>>, @@ -710,7 +716,7 @@ do_interesting(Module) ->  encode_decode(doc) ->      ["test binary:encode_unsigned/1,2 and binary:decode_unsigned/1,2"];  encode_decode(Config) when is_list(Config) -> -    ?line random:seed({1271,769940,559934}), +    rand:seed(exsplus, {1271,769940,559934}),      ?line ok = encode_decode_loop({1,200},1000), % Need to be long enough  						 % to create offheap binaries      ok. @@ -817,7 +823,7 @@ copy(Config) when is_list(Config) ->      ?line badarg = ?MASK_ERROR(binary:copy(<<1,2,3>>,  					   16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)),      ?line <<>> = binary:copy(<<>>,10000), -    ?line random:seed({1271,769940,559934}), +    rand:seed(exsplus, {1271,769940,559934}),      ?line ok = random_copy(3000),      ?line erts_debug:set_internal_state(available_internal_state,true),      ?line io:format("oldlimit: ~p~n", @@ -855,7 +861,7 @@ random_copy(0) ->      ok;  random_copy(N) ->      Str = random_string({0,N}), -    Num = random:uniform(N div 10+1), +    Num = rand:uniform(N div 10+1),      A = ?MASK_ERROR(binary:copy(Str,Num)),      B = ?MASK_ERROR(binref:copy(Str,Num)),      C = ?MASK_ERROR(binary:copy(make_unaligned(Str),Num)), @@ -896,7 +902,7 @@ bin_to_list(Config) when is_list(Config) ->      ?line [5] = lists:nthtail(byte_size(X)-1,LX),      ?line [0,5] = lists:nthtail(byte_size(X)-2,LX),      ?line [0,5] = lists:nthtail(byte_size(Y)-2,LY), -    ?line random:seed({1271,769940,559934}), +    rand:seed(exsplus, {1271,769940,559934}),      ?line ok = random_bin_to_list(5000),      ok. @@ -963,7 +969,7 @@ parts(Config) when is_list(Config) ->      ?line badarg = ?MASK_ERROR(binary:part(Simple,{-1,0})),      ?line badarg = ?MASK_ERROR(binary:part(Simple,{7,2})),      ?line <<8>> = binary:part(Simple,{7,1}), -    ?line random:seed({1271,769940,559934}), +    rand:seed(exsplus, {1271,769940,559934}),      ?line random_parts(5000),      ok. @@ -987,15 +993,15 @@ random_parts(N) ->  random_parts(0,_) ->      [];  random_parts(X,N) -> -    Pos = random:uniform(N), -    Len = random:uniform((Pos * 12) div 10), +    Pos = rand:uniform(N), +    Len = rand:uniform((Pos * 12) div 10),      [{Pos,Len} | random_parts(X-1,N)].  random_ref_comp(doc) ->      ["Test pseudorandomly generated cases against reference imlementation"];  random_ref_comp(Config) when is_list(Config) ->      put(success_counter,0), -    random:seed({1271,769940,559934}), +    rand:seed(exsplus, {1271,769940,559934}),      Nr = {1,40},      Hr = {30,1000},      I1 = 1500, @@ -1025,7 +1031,7 @@ random_ref_sr_comp(doc) ->      ["Test pseudorandomly generated cases against reference imlementation of split and replace"];  random_ref_sr_comp(Config) when is_list(Config) ->      put(success_counter,0), -    random:seed({1271,769940,559934}), +    rand:seed(exsplus, {1271,769940,559934}),      Nr = {1,40},      Hr = {30,1000},      I1 = 1500, @@ -1043,7 +1049,7 @@ random_ref_fla_comp(doc) ->      ["Test pseudorandomly generated cases against reference imlementation of split and replace"];  random_ref_fla_comp(Config) when is_list(Config) ->      ?line put(success_counter,0), -    ?line random:seed({1271,769940,559934}), +    rand:seed(exsplus, {1271,769940,559934}),      ?line do_random_first_comp(5000,{1,1000}),      ?line do_random_last_comp(5000,{1,1000}),      ?line do_random_at_comp(5000,{1,1000}), @@ -1377,24 +1383,24 @@ one_random(N) ->  random_number({Min,Max}) -> % Min and Max are *length* of number in                              % decimal positions -    X = random:uniform(Max - Min + 1) + Min - 1, -    list_to_integer([one_random_number(random:uniform(10)) || _ <- lists:seq(1,X)]). +    X = rand:uniform(Max - Min + 1) + Min - 1, +    list_to_integer([one_random_number(rand:uniform(10)) || _ <- lists:seq(1,X)]).  random_length({Min,Max}) -> -    random:uniform(Max - Min + 1) + Min - 1. +    rand:uniform(Max - Min + 1) + Min - 1.  random_string({Min,Max}) -> -    X = random:uniform(Max - Min + 1) + Min - 1, -    list_to_binary([one_random(random:uniform(68)) || _ <- lists:seq(1,X)]). +    X = rand:uniform(Max - Min + 1) + Min - 1, +    list_to_binary([one_random(rand:uniform(68)) || _ <- lists:seq(1,X)]).  random_substring({Min,Max},Hay) -> -    X = random:uniform(Max - Min + 1) + Min - 1, +    X = rand:uniform(Max - Min + 1) + Min - 1,      Y = byte_size(Hay),      Z = if  	    X > Y -> Y;  	    true -> X  	end,      PMax = Y - Z, -    Pos = random:uniform(PMax + 1) - 1, +    Pos = rand:uniform(PMax + 1) - 1,      <<_:Pos/binary,Res:Z/binary,_/binary>> = Hay,      Res. diff --git a/lib/stdlib/test/dict_SUITE.erl b/lib/stdlib/test/dict_SUITE.erl index 648154ebbe..aff73b176d 100644 --- a/lib/stdlib/test/dict_SUITE.erl +++ b/lib/stdlib/test/dict_SUITE.erl @@ -108,7 +108,7 @@ iterate_1(M) ->      M(empty, []).  iterate_2(M) -> -    random:seed(1, 2, 42), +    rand:seed(exsplus, {1,2,42}),      iter_tree(M, 1000).  iter_tree(_M, 0) -> @@ -117,7 +117,7 @@ iter_tree(M, N) ->      L = [{I, I} || I <- lists:seq(1, N)],      T = M(from_list, L),      L = lists:reverse(iterate_tree(M, T)), -    R = random:uniform(N), +    R = rand:uniform(N),      KV = lists:reverse(iterate_tree_from(M, R, T)),      KV = [P || P={K,_} <- L, K >= R],      iter_tree(M, N-1). @@ -156,7 +156,7 @@ test_all(Tester) ->  spawn_tester(M, Tester) ->      Parent = self(),      spawn_link(fun() -> -		       random:seed(1, 2, 42), +		       rand:seed(exsplus, {1,2,42}),  		       S = Tester(M),  		       Res = {M(size, S),lists:sort(M(to_list, S))},  		       Parent ! {result,self(),Res} @@ -194,12 +194,12 @@ rnd_list_1(0, Acc) ->      Acc;  rnd_list_1(N, Acc) ->      Key = atomic_rnd_term(), -    Value = random:uniform(100), +    Value = rand:uniform(100),      rnd_list_1(N-1, [{Key,Value}|Acc]).  atomic_rnd_term() -> -    case random:uniform(3) of -	 1 -> list_to_atom(integer_to_list($\s+random:uniform(94))++"rnd"); -	 2 -> random:uniform(); -	 3 -> random:uniform(50)-37 +    case rand:uniform(3) of +	 1 -> list_to_atom(integer_to_list($\s+rand:uniform(94))++"rnd"); +	 2 -> rand:uniform(); +	 3 -> rand:uniform(50)-37      end. diff --git a/lib/stdlib/test/epp_SUITE.erl b/lib/stdlib/test/epp_SUITE.erl index 4e5df661b3..4c007e76ad 100644 --- a/lib/stdlib/test/epp_SUITE.erl +++ b/lib/stdlib/test/epp_SUITE.erl @@ -27,7 +27,7 @@           pmod/1, not_circular/1, skip_header/1, otp_6277/1, otp_7702/1,           otp_8130/1, overload_mac/1, otp_8388/1, otp_8470/1, otp_8503/1,           otp_8562/1, otp_8665/1, otp_8911/1, otp_10302/1, otp_10820/1, -         otp_11728/1, encoding/1]). +         otp_11728/1, encoding/1, extends/1]).  -export([epp_parse_erl_form/2]). @@ -70,7 +70,7 @@ all() ->       not_circular, skip_header, otp_6277, otp_7702, otp_8130,       overload_mac, otp_8388, otp_8470, otp_8503, otp_8562,       otp_8665, otp_8911, otp_10302, otp_10820, otp_11728, -     encoding]. +     encoding, extends].  groups() ->       [{upcase_mac, [], [upcase_mac_1, upcase_mac_2]}, @@ -621,6 +621,10 @@ otp_8130(Config) when is_list(Config) ->               "                2 end,\n"               "          7),\n"               "   {2,7} =\n" +             "      ?M1(begin 1 = fun _Name () -> 1 end(),\n" +             "                2 end,\n" +             "          7),\n" +             "   {2,7} =\n"               "      ?M1(begin 1 = fun t0/0(),\n"               "                2 end,\n"               "          7),\n" @@ -645,6 +649,9 @@ otp_8130(Config) when is_list(Config) ->               "      ?M1(begin yes = try 1 of 1 -> yes after foo end,\n"               "                2 end,\n"               "          7),\n" +             "   {[42],7} =\n" +             "      ?M1([42],\n" +             "          7),\n"               "ok.\n">>,             ok}, @@ -728,11 +735,16 @@ otp_8130(Config) when is_list(Config) ->             {errors,[{{2,2},epp,{include,lib,"$apa/foo.hrl"}}],[]}}, -          {otp_8130_c9, +          {otp_8130_c9a,             <<"-define(S, ?S).\n"               "t() -> ?S.\n">>,             {errors,[{{2,9},epp,{circular,'S', none}}],[]}}, +          {otp_8130_c9b, +           <<"-define(S(), ?S()).\n" +             "t() -> ?S().\n">>, +           {errors,[{{2,9},epp,{circular,'S', 0}}],[]}}, +            {otp_8130_c10,             <<"\n-file.">>,             {errors,[{{2,2},epp,{bad,file}}],[]}}, @@ -799,6 +811,10 @@ otp_8130(Config) when is_list(Config) ->             <<"\n-include(\"no such file.erl\").\n">>,             {errors,[{{2,2},epp,{include,file,"no such file.erl"}}],[]}}, +          {otp_8130_c25, +           <<"\n-define(A.\n">>, +           {errors,[{{2,2},epp,{bad,define}}],[]}}, +            {otp_8130_7,             <<"-record(b, {b}).\n"               "-define(A, {{a,#b.b.\n" @@ -826,14 +842,14 @@ otp_8130(Config) when is_list(Config) ->                                 "-define(a, 3.14).\n"                                 "t() -> ?a.\n"),      ?line {ok,Epp} = epp:open(File, []), -    ?line ['BASE_MODULE','BASE_MODULE_STRING','BEAM','FILE','LINE', -           'MACHINE','MODULE','MODULE_STRING'] = macs(Epp), +    PreDefMacs = macs(Epp), +    ['BASE_MODULE','BASE_MODULE_STRING','BEAM','FILE','LINE', +     'MACHINE','MODULE','MODULE_STRING'] = PreDefMacs,      ?line {ok,[{'-',_},{atom,_,file}|_]} = epp:scan_erl_form(Epp),      ?line {ok,[{'-',_},{atom,_,module}|_]} = epp:scan_erl_form(Epp),      ?line {ok,[{atom,_,t}|_]} = epp:scan_erl_form(Epp),      ?line {eof,_} = epp:scan_erl_form(Epp), -    ?line ['BASE_MODULE','BASE_MODULE_STRING','BEAM','FILE','LINE', -           'MACHINE','MODULE','MODULE_STRING',a] = macs(Epp), +    [a] = macs(Epp) -- PreDefMacs,      ?line epp:close(Epp),      %% escript @@ -1476,6 +1492,20 @@ encoding(Config) when is_list(Config) ->  	epp_parse_file(ErlFile, [{default_encoding,utf8},extra]),      ok. +extends(Config) -> +    Cs = [{extends_c1, +	   <<"-extends(some.other.module).\n">>, +	   {errors,[{1,erl_parse,["syntax error before: ","'.'"]}],[]}}], +    [] = compile(Config, Cs), + +    Ts = [{extends_1, +	   <<"-extends(some_other_module).\n" +	     "t() -> {?BASE_MODULE,?BASE_MODULE_STRING}.\n">>, +	   {some_other_module,"some_other_module"}}], + +    [] = run(Config, Ts), +    ok. +  check(Config, Tests) ->      eval_tests(Config, fun check_test/2, Tests). @@ -1504,15 +1534,17 @@ eval_tests(Config, Fun, Tests) ->  check_test(Config, Test) ->      Filename = "epp_test.erl", -    ?line PrivDir = ?config(priv_dir, Config), -    ?line File = filename:join(PrivDir, Filename), -    ?line ok = file:write_file(File, Test), -    ?line case epp:parse_file(File, [PrivDir], []) of -              {ok,Forms} -> -                  [E || E={error,_} <- Forms]; -              {error,Error} -> -                  Error -          end. +    PrivDir = ?config(priv_dir, Config), +    File = filename:join(PrivDir, Filename), +    ok = file:write_file(File, Test), +    case epp:parse_file(File, [PrivDir], []) of +	{ok,Forms} -> +	    Errors = [E || E={error,_} <- Forms], +	    call_format_error([E || {error,E} <- Errors]), +	    Errors; +	{error,Error} -> +	    Error +    end.  compile_test(Config, Test0) ->      Test = [<<"-module(epp_test). -compile(export_all). ">>, Test0], @@ -1528,8 +1560,11 @@ compile_test(Config, Test0) ->  warnings(File, Ws) ->      case lists:append([W || {F, W} <- Ws, F =:= File]) of -        [] -> []; -        L -> {warnings, L} +        [] -> +	    []; +        L -> +	    call_format_error(L), +	    {warnings, L}      end.  compile_file(File, Opts) -> @@ -1540,12 +1575,20 @@ compile_file(File, Opts) ->      end.  errs([{File,Es}|L], File) -> +    call_format_error(Es),      Es ++ errs(L, File);  errs([_|L], File) ->      errs(L, File);  errs([], _File) ->      []. +%% Smoke test and coverage of format_error/1. +call_format_error([{_,M,E}|T]) -> +    _ = M:format_error(E), +    call_format_error(T); +call_format_error([]) -> +    ok. +  epp_parse_file(File, Opts) ->      case epp:parse_file(File, Opts) of          {ok, Forms} -> diff --git a/lib/stdlib/test/erl_anno_SUITE.erl b/lib/stdlib/test/erl_anno_SUITE.erl index 66b02151a0..0369455846 100644 --- a/lib/stdlib/test/erl_anno_SUITE.erl +++ b/lib/stdlib/test/erl_anno_SUITE.erl @@ -34,7 +34,7 @@           init_per_testcase/2, end_per_testcase/2]).  -export([new/1, is_anno/1, generated/1, end_location/1, file/1, -         line/1, location/1, record/1, text/1, bad/1, neg_line/1]). +         line/1, location/1, record/1, text/1, bad/1]).  -export([parse_abstract/1, mapfold_anno/1]). @@ -43,7 +43,7 @@ all() ->  groups() ->      [{anno, [], [new, is_anno, generated, end_location, file, -                 line, location, record, text, bad, neg_line]}, +                 line, location, record, text, bad]},       {parse, [], [parse_abstract, mapfold_anno]}].  suite() -> [{ct_hooks,[ts_install_cth]}]. @@ -229,74 +229,6 @@ bad(_Config) ->          (catch erl_anno:record(bad)), % 1st arg not opaque      ok. -neg_line(doc) -> -    ["Test negative line numbers (OTP 18)"]; -neg_line(_Config) -> -    neg_line1(false), -    neg_line1(true), -    ok. - -neg_line1(TextToo) -> -    Minus8_0 = erl_anno:new(-8), -    Plus8_0 = erl_anno:new(8), -    Minus8C_0 = erl_anno:new({-8, 17}), -    Plus8C_0 = erl_anno:new({8, 17}), - -    [Minus8, Plus8, Minus8C, Plus8C] = -        [case TextToo of -             true -> -                 erl_anno:set_text("foo", A); -             false -> -                 A -         end || A <- [Minus8_0, Plus8_0, Minus8C_0, Plus8C_0]], - -    tst(-3, erl_anno:set_location(3, Minus8)), -    tst(-3, erl_anno:set_location(-3, Plus8)), -    tst(-3, erl_anno:set_location(-3, Minus8)), -    tst({-3,9}, erl_anno:set_location({3, 9}, Minus8)), -    tst({-3,9}, erl_anno:set_location({-3, 9}, Plus8)), -    tst({-3,9}, erl_anno:set_location({-3, 9}, Minus8)), -    tst(-3, erl_anno:set_location(3, Minus8C)), -    tst(-3, erl_anno:set_location(-3, Plus8C)), -    tst(-3, erl_anno:set_location(-3, Minus8C)), -    tst({-3,9}, erl_anno:set_location({3, 9}, Minus8C)), -    tst({-3,9}, erl_anno:set_location({-3, 9}, Plus8C)), -    tst({-3,9}, erl_anno:set_location({-3, 9}, Minus8C)), - -    tst(-8, erl_anno:set_generated(true, Plus8)), -    tst(-8, erl_anno:set_generated(true, Minus8)), -    tst({-8,17}, erl_anno:set_generated(true, Plus8C)), -    tst({-8,17}, erl_anno:set_generated(true, Minus8C)), -    tst(8, erl_anno:set_generated(false, Plus8)), -    tst(8, erl_anno:set_generated(false, Minus8)), -    tst({8,17}, erl_anno:set_generated(false, Plus8C)), -    tst({8,17}, erl_anno:set_generated(false, Minus8C)), - -    tst(-3, erl_anno:set_line(3, Minus8)), -    tst(-3, erl_anno:set_line(-3, Plus8)), -    tst(-3, erl_anno:set_line(-3, Minus8)), -    tst({-3,17}, erl_anno:set_line(3, Minus8C)), -    tst({-3,17}, erl_anno:set_line(-3, Plus8C)), -    tst({-3,17}, erl_anno:set_line(-3, Minus8C)), -    ok. - -tst(Term, Anno) -> -    ?format("Term: ~p\n", [Term]), -    ?format("Anno: ~p\n", [Anno]), -    case anno_to_term(Anno) of -        Term -> -            ok; -        Else -> -            case lists:keyfind(location, 1, Else) of -                {location, Term} -> -                    ok; -                _Else2 -> -                    ?format("Else2 ~p\n", [_Else2]), -                    io:format("expected ~p\n got     ~p\n", [Term, Else]), -                    exit({Term, Else}) -            end -    end. -  parse_abstract(doc) ->      ["Test erl_parse:new_anno/1, erl_parse:anno_to_term/1"       ", and erl_parse:anno_from_term/1"]; diff --git a/lib/stdlib/test/erl_lint_SUITE.erl b/lib/stdlib/test/erl_lint_SUITE.erl index 5347ccaf1f..3c746a13d7 100644 --- a/lib/stdlib/test/erl_lint_SUITE.erl +++ b/lib/stdlib/test/erl_lint_SUITE.erl @@ -65,7 +65,7 @@  	  too_many_arguments/1,  	  basic_errors/1,bin_syntax_errors/1,            predef/1, -          maps/1,maps_type/1,otp_11851/1,otp_12195/1 +          maps/1,maps_type/1,otp_11851/1,otp_11879/1          ]).  % Default timetrap timeout (set in init_per_testcase). @@ -94,7 +94,7 @@ all() ->       bif_clash, behaviour_basic, behaviour_multiple, otp_11861,       otp_7550, otp_8051, format_warn, {group, on_load},       too_many_arguments, basic_errors, bin_syntax_errors, predef, -     maps, maps_type, otp_11851, otp_12195]. +     maps, maps_type, otp_11851, otp_11879].  groups() ->       [{unused_vars_warn, [], @@ -1296,12 +1296,16 @@ unsized_binary_in_bin_gen_pattern(Config) when is_list(Config) ->      Ts = [{unsized_binary_in_bin_gen_pattern,  	   <<"t({bc,binary,Bin}) ->  		  << <<X,Tail/binary>> || <<X,Tail/binary>> <= Bin >>; +	      t({bc,bytes,Bin}) -> +		  << <<X,Tail/binary>> || <<X,Tail/bytes>> <= Bin >>;  	      t({bc,bits,Bin}) ->  		  << <<X,Tail/bits>> || <<X,Tail/bits>> <= Bin >>;  	      t({bc,bitstring,Bin}) ->  		  << <<X,Tail/bits>> || <<X,Tail/bitstring>> <= Bin >>;  	      t({lc,binary,Bin}) ->  		  [ {X,Tail} || <<X,Tail/binary>> <= Bin ]; +	      t({lc,bytes,Bin}) -> +		  [ {X,Tail} || <<X,Tail/bytes>> <= Bin ];  	      t({lc,bits,Bin}) ->  		  [ {X,Tail} || <<X,Tail/bits>> <= Bin ];  	      t({lc,bitstring,Bin}) -> @@ -1313,7 +1317,9 @@ unsized_binary_in_bin_gen_pattern(Config) when is_list(Config) ->  	     {6,erl_lint,unsized_binary_in_bin_gen_pattern},  	     {8,erl_lint,unsized_binary_in_bin_gen_pattern},  	     {10,erl_lint,unsized_binary_in_bin_gen_pattern}, -	     {12,erl_lint,unsized_binary_in_bin_gen_pattern}], +	     {12,erl_lint,unsized_binary_in_bin_gen_pattern}, +	     {14,erl_lint,unsized_binary_in_bin_gen_pattern}, +	     {16,erl_lint,unsized_binary_in_bin_gen_pattern}],  	     []}}],      [] = run(Config, Ts),      ok. @@ -3843,38 +3849,27 @@ otp_11851(Config) when is_list(Config) ->      [] = run(Config, Ts),      ok. -otp_12195(doc) -> -    "OTP-12195: Check obsolete types (tailor made for OTP 18)."; -otp_12195(Config) when is_list(Config) -> -    Ts = [{otp_12195_1, -           <<"-export_type([r1/0]). -              -type r1() :: erl_scan:line() -                          | erl_scan:column() -                          | erl_scan:location() -                          | erl_anno:line().">>, -           [], -           {warnings,[{2,erl_lint, -                       {deprecated_type,{erl_scan,line,0}, -                        "deprecated (will be removed in OTP 19); " -                        "use erl_anno:line() instead"}}, -                      {3,erl_lint, -                       {deprecated_type,{erl_scan,column,0}, -                        "deprecated (will be removed in OTP 19); use " -                        "erl_anno:column() instead"}}, -                      {4,erl_lint, -                       {deprecated_type,{erl_scan,location,0}, -                        "deprecated (will be removed in OTP 19); " -                        "use erl_anno:location() instead"}}]}}, -          {otp_12195_2, -           <<"-export_type([r1/0]). -              -compile(nowarn_deprecated_type). -              -type r1() :: erl_scan:line() -                          | erl_scan:column() -                          | erl_scan:location() -                          | erl_anno:line().">>, -           [], -           []}], -    [] = run(Config, Ts), +otp_11879(doc) -> +    "OTP-11879: The -spec f/a :: (As) -> B; syntax removed, " +    "and is_subtype/2 deprecated"; +otp_11879(_Config) -> +    Fs = [{attribute,0,file,{"file.erl",0}}, +          {attribute,0,module,m}, +          {attribute,1,spec, +           {{f,1}, +            [{type,2,'fun',[{type,3,product,[{var,4,'V1'}, +                                             {var,5,'V1'}]}, +                            {type,6,integer,[]}]}]}}, +          {attribute,20,callback, +           {{cb,21}, +            [{type,22,'fun',[{type,23,product,[{var,24,'V1'}, +                                               {var,25,'V1'}]}, +                             {type,6,integer,[]}]}]}}], +    {error,[{"file.erl", +             [{1,erl_lint,{spec_fun_undefined,{f,1}}}, +              {2,erl_lint,spec_wrong_arity}, +              {22,erl_lint,callback_wrong_arity}]}], +     []} = compile:forms(Fs, [return,report]),      ok.  run(Config, Tests) -> diff --git a/lib/stdlib/test/erl_pp_SUITE.erl b/lib/stdlib/test/erl_pp_SUITE.erl index 92e2764c65..8a128b3815 100644 --- a/lib/stdlib/test/erl_pp_SUITE.erl +++ b/lib/stdlib/test/erl_pp_SUITE.erl @@ -876,6 +876,9 @@ type_examples() ->       {ex30,<<"-type t99() ::"         "{t2(),'\\'t::4'(),t5(),t6(),t7(),t8(),t10(),t14(),"         "t15(),t20(),t21(), t22(),t25()}. ">>}, +     %% Writing constraints as is_subtype(V, T) is not supported since +     %% Erlang/OTP 19.0, but as long as the parser recognizes the +     %% is_subtype(V, T) syntax, we need a few examples of the syntax.       {ex31,<<"-spec t1(FooBar :: t99()) -> t99();"                            "(t2()) -> t2();"                            "('\\'t::4'()) -> '\\'t::4'() when is_subtype('\\'t::4'(), t24);" @@ -928,7 +931,9 @@ otp_8522(Config) when is_list(Config) ->      ?line {ok, _} = compile:file(FileName, [{outdir,?privdir},debug_info]),      BF = filename("otp_8522", Config),      ?line {ok, A} = beam_lib:chunks(BF, [abstract_code]), -    ?line 5 = count_atom(A, undefined), +    %% OTP-12719: Since 'undefined' is no longer added by the Erlang +    %% Parser, the number of 'undefined' is 4. It used to be 5. +    ?line 4 = count_atom(A, undefined),      ok.  count_atom(A, A) -> @@ -998,18 +1003,10 @@ otp_8567(Config) when is_list(Config) ->            "t() ->\n"            "    3.\n"            "\n" -          "-spec(t1/1 :: (ot()) -> ot1()).\n" -          "t1(A) ->\n" -          "    A.\n" -          "\n"            "-spec(t2 (ot()) -> ot1()).\n"            "t2(A) ->\n"            "    A.\n"            "\n" -          "-spec(otp_8567:t3/1 :: (ot()) -> ot1()).\n" -          "t3(A) ->\n" -          "    A.\n" -          "\n"            "-spec(otp_8567:t4 (ot()) -> ot1()).\n"            "t4(A) ->\n"            "    A.\n">>, @@ -1065,7 +1062,7 @@ otp_9147(Config) when is_list(Config) ->      ?line {ok, Bin} = file:read_file(PFileName),      %% The parentheses around "F1 :: a | b" are new (bugfix).      ?line true =  -        lists:member("-record(undef,{f1 :: undefined | (F1 :: a | b)}).", +        lists:member("-record(undef,{f1 :: F1 :: a | b}).",                       string:tokens(binary_to_list(Bin), "\n")),      ok. diff --git a/lib/stdlib/test/erl_scan_SUITE.erl b/lib/stdlib/test/erl_scan_SUITE.erl index 12ea3d128c..db669aae99 100644 --- a/lib/stdlib/test/erl_scan_SUITE.erl +++ b/lib/stdlib/test/erl_scan_SUITE.erl @@ -191,8 +191,7 @@ otp_7810(Config) when is_list(Config) ->      ?line ok = more_chars(),      ?line ok = more_options(), -    ?line ok = attributes_info(), -    ?line ok = set_attribute(), +    ?line ok = anno_info(),      ok. @@ -269,7 +268,7 @@ punctuations() ->  comments() ->      ?line test("a %%\n b"), -    {ok,[],1} = erl_scan_string("%"), +    ?line {ok,[],1} = erl_scan_string("%"),      ?line test("a %%\n b"),      {ok,[{atom,{1,1},a},{atom,{2,2},b}],{2,3}} =          erl_scan_string("a %%\n b", {1,1}), @@ -338,7 +337,7 @@ base_integers() ->               erl_scan:string(Str)       end || {BS,S} <- [{"3","3"},{"15","f"}, {"12","c"}] ], -    {ok,[{integer,1,239},{'@',1}],1} = erl_scan_string("16#ef@"), +    ?line {ok,[{integer,1,239},{'@',1}],1} = erl_scan_string("16#ef@"),      {ok,[{integer,{1,1},239},{'@',{1,6}}],{1,7}} =          erl_scan_string("16#ef@", {1,1}, []),      {ok,[{integer,{1,1},14},{atom,{1,5},g@}],{1,7}} = @@ -387,20 +386,15 @@ dots() ->           R2 = erl_scan_string(S, {1,1}, [])       end || {S, R, R2} <- Dot], -    ?line {ok,[{dot,_}=T1],{1,2}} = erl_scan:string(".", {1,1}, text), -    ?line [{column,1},{length,1},{line,1},{text,"."}] = -        erl_scan:token_info(T1, [column, length, line, text]), -    ?line {ok,[{dot,_}=T2],{1,3}} = erl_scan:string(".%", {1,1}, text), -    ?line [{column,1},{length,1},{line,1},{text,"."}] = -        erl_scan:token_info(T2, [column, length, line, text]), -    ?line {ok,[{dot,_}=T3],{1,6}} = +    {ok,[{dot,_}=T1],{1,2}} = erl_scan:string(".", {1,1}, text), +    [1, 1, "."] = token_info(T1), +    {ok,[{dot,_}=T2],{1,3}} = erl_scan:string(".%", {1,1}, text), +    [1, 1, "."] = token_info(T2), +    {ok,[{dot,_}=T3],{1,6}} =          erl_scan:string(".% öh", {1,1}, text), -    ?line [{column,1},{length,1},{line,1},{text,"."}] = -        erl_scan:token_info(T3, [column, length, line, text]), -    ?line {error,{{1,2},erl_scan,char},{1,3}} = -        erl_scan:string(".$", {1,1}), -    ?line {error,{{1,2},erl_scan,char},{1,4}} = -        erl_scan:string(".$\\", {1,1}), +    [1, 1, "."] = token_info(T3), +    {error,{{1,2},erl_scan,char},{1,3}} = erl_scan:string(".$", {1,1}), +    {error,{{1,2},erl_scan,char},{1,4}} = erl_scan:string(".$\\", {1,1}),      test_string(". ", [{dot,{1,1}}]),      test_string(".  ", [{dot,{1,1}}]), @@ -413,18 +407,18 @@ dots() ->      test_string(".a", [{'.',{1,1}},{atom,{1,2},a}]),      test_string("%. \n. ", [{dot,{2,1}}]), -    ?line {more,C} = erl_scan:tokens([], "%. ",{1,1}, return), +    {more,C} = erl_scan:tokens([], "%. ",{1,1}, return),      {done,{ok,[{comment,{1,1},"%. "},                 {white_space,{1,4},"\n"},                 {dot,{2,1}}],             {2,3}}, ""} =          erl_scan_tokens(C, "\n. ", {1,1}, return), % any loc, any options -    ?line [test_string(S, R) || -              {S, R} <- [{".$\n",   [{'.',{1,1}},{char,{1,2},$\n}]}, -                         {"$\\\n",  [{char,{1,1},$\n}]}, -                         {"'\\\n'", [{atom,{1,1},'\n'}]}, -                         {"$\n",    [{char,{1,1},$\n}]}] ], +    [test_string(S, R) || +        {S, R} <- [{".$\n",   [{'.',{1,1}},{char,{1,2},$\n}]}, +                   {"$\\\n",  [{char,{1,1},$\n}]}, +                   {"'\\\n'", [{atom,{1,1},'\n'}]}, +                   {"$\n",    [{char,{1,1},$\n}]}] ],      ok.  chars() -> @@ -540,8 +534,8 @@ eof() ->      %% A dot followed by eof is special:      ?line {more, C} = erl_scan:tokens([], "a.", 1), -    {done,{ok,[{atom,1,a},{dot,1}],1},eof} = erl_scan_tokens(C,eof,1), -    {ok,[{atom,1,foo},{dot,1}],1} = erl_scan_string("foo."), +    ?line {done,{ok,[{atom,1,a},{dot,1}],1},eof} = erl_scan_tokens(C,eof,1), +    ?line {ok,[{atom,1,foo},{dot,1}],1} = erl_scan_string("foo."),      %% With column.      {more, CCol} = erl_scan:tokens([], "a.", {1,1}), @@ -655,145 +649,72 @@ options() ->      ok.  more_options() -> -    ?line {ok,[{atom,A1,foo}],{19,20}} = +    {ok,[{atom,_,foo}=T1],{19,20}} =          erl_scan:string("foo", {19,17},[]), -    ?line [{column,17},{line,19}] = erl_scan:attributes_info(A1), -    ?line {done,{ok,[{atom,A2,foo},{dot,_}],{19,22}},[]} = +    {19,17} = erl_scan:location(T1), +    {done,{ok,[{atom,_,foo}=T2,{dot,_}],{19,22}},[]} =          erl_scan:tokens([], "foo. ", {19,17}, [bad_opt]), % type error -    ?line [{column,17},{line,19}] = erl_scan:attributes_info(A2), -    ?line {ok,[{atom,A3,foo}],{19,20}} = +    {19,17} = erl_scan:location(T2), +    {ok,[{atom,_,foo}=T3],{19,20}} =          erl_scan:string("foo", {19,17},[text]), -    ?line [{column,17},{length,3},{line,19},{text,"foo"}] = -        erl_scan:attributes_info(A3), +    {19,17} = erl_scan:location(T3), +    "foo" = erl_scan:text(T3), -    ?line {ok,[{atom,A4,foo}],1} = erl_scan:string("foo", 1, [text]), -    ?line [{length,3},{line,1},{text,"foo"}] = erl_scan:attributes_info(A4), +    {ok,[{atom,_,foo}=T4],1} = erl_scan:string("foo", 1, [text]), +    1 = erl_scan:line(T4), +    1 = erl_scan:location(T4), +    "foo" = erl_scan:text(T4),      ok.  token_info() -> -    ?line {ok,[T1],_} = erl_scan:string("foo", {1,18}, [text]), +    {ok,[T1],_} = erl_scan:string("foo", {1,18}, [text]),      {'EXIT',{badarg,_}} = -        (catch {foo, erl_scan:token_info(T1, foo)}), % type error -    ?line {line,1} = erl_scan:token_info(T1, line), -    ?line {column,18} = erl_scan:token_info(T1, column), -    ?line {length,3} = erl_scan:token_info(T1, length), -    ?line {text,"foo"} = erl_scan:token_info(T1, text), -    ?line [{category,atom},{column,18},{length,3},{line,1}, -           {symbol,foo},{text,"foo"}] = -        erl_scan:token_info(T1), -    ?line [{length,3},{column,18}] = -        erl_scan:token_info(T1, [length, column]), -    ?line [{location,{1,18}}] = -        erl_scan:token_info(T1, [location]), -    ?line {category,atom} = erl_scan:token_info(T1, category), -    ?line [{symbol,foo}] = erl_scan:token_info(T1, [symbol]), - -    ?line {ok,[T2],_} = erl_scan:string("foo", 1, []), -    ?line {line,1} = erl_scan:token_info(T2, line), -    ?line undefined = erl_scan:token_info(T2, column), -    ?line undefined = erl_scan:token_info(T2, length), -    ?line undefined = erl_scan:token_info(T2, text), -    ?line {location,1} = erl_scan:token_info(T2, location), -    ?line [{category,atom},{line,1},{symbol,foo}] = erl_scan:token_info(T2), -    ?line [{line,1}] = erl_scan:token_info(T2, [length, line]), - -    ?line {ok,[T3],_} = erl_scan:string("=", 1, []), -    ?line [{line,1}] = erl_scan:token_info(T3, [column, line]), -    ?line {category,'='} = erl_scan:token_info(T3, category), -    ?line [{symbol,'='}] = erl_scan:token_info(T3, [symbol]), +        (catch {foo, erl_scan:category(foo)}), % type error +    {'EXIT',{badarg,_}} = +        (catch {foo, erl_scan:symbol(foo)}), % type error +    atom = erl_scan:category(T1), +    foo = erl_scan:symbol(T1), + +    {ok,[T2],_} = erl_scan:string("foo", 1, []), +    1 = erl_scan:line(T2), +    undefined = erl_scan:column(T2), +    undefined = erl_scan:text(T2), +    1 = erl_scan:location(T2), + +    {ok,[T3],_} = erl_scan:string("=", 1, []), +    '=' = erl_scan:category(T3), +    '=' = erl_scan:symbol(T3),      ok. -attributes_info() -> -    ?line {'EXIT',_} = -        (catch {foo,erl_scan:attributes_info(foo)}), % type error -    [{line,18}] = erl_scan:attributes_info(erl_anno:new(18)), -    {location,19} = -        erl_scan:attributes_info(erl_anno:new(19), location), -    ?line {ok,[{atom,A0,foo}],_} = erl_scan:string("foo", 19, [text]), -    ?line {location,19} = erl_scan:attributes_info(A0, location), - -    ?line {ok,[{atom,A3,foo}],_} = erl_scan:string("foo", {1,3}, [text]), -    ?line {line,1} = erl_scan:attributes_info(A3, line), -    ?line {column,3} = erl_scan:attributes_info(A3, column), -    ?line {location,{1,3}} = erl_scan:attributes_info(A3, location), -    ?line {text,"foo"} = erl_scan:attributes_info(A3, text), - -    ?line {ok,[{atom,A4,foo}],_} = erl_scan:string("foo", 2, [text]), -    ?line {line,2} = erl_scan:attributes_info(A4, line), -    ?line undefined = erl_scan:attributes_info(A4, column), -    ?line {location,2} = erl_scan:attributes_info(A4, location), -    ?line {text,"foo"} = erl_scan:attributes_info(A4, text), - -    ?line {ok,[{atom,A5,foo}],_} = erl_scan:string("foo", {1,3}, []), -    ?line {line,1} = erl_scan:attributes_info(A5, line), -    ?line {column,3} = erl_scan:attributes_info(A5, column), -    ?line {location,{1,3}} = erl_scan:attributes_info(A5, location), -    ?line undefined = erl_scan:attributes_info(A5, text), - -    ?line undefined = erl_scan:attributes_info([], line), % type error +anno_info() -> +    {'EXIT',_} = +        (catch {foo,erl_scan:line(foo)}), % type error +    {ok,[{atom,_,foo}=T0],_} = erl_scan:string("foo", 19, [text]), +    19 = erl_scan:location(T0), +    19 = erl_scan:end_location(T0), + +    {ok,[{atom,_,foo}=T3],_} = erl_scan:string("foo", {1,3}, [text]), +    1 = erl_scan:line(T3), +    3 = erl_scan:column(T3), +    {1,3} = erl_scan:location(T3), +    {1,6} = erl_scan:end_location(T3), +    "foo" = erl_scan:text(T3), + +    {ok,[{atom,_,foo}=T4],_} = erl_scan:string("foo", 2, [text]), +    2 = erl_scan:line(T4), +    undefined = erl_scan:column(T4), +    2 = erl_scan:location(T4), +    "foo" = erl_scan:text(T4), + +    {ok,[{atom,_,foo}=T5],_} = erl_scan:string("foo", {1,3}, []), +    1 = erl_scan:line(T5), +    3 = erl_scan:column(T5), +    {1,3} = erl_scan:location(T5), +    undefined = erl_scan:text(T5),      ok. -set_attribute() -> -    F = fun(Line) -> -Line end, -    Anno2 = erl_anno:new(2), -    A0 = erl_scan:set_attribute(line, Anno2, F), -    {line, -2} = erl_scan:attributes_info(A0, line), -    ?line {ok,[{atom,A1,foo}],_} = erl_scan:string("foo", {9,17}), -    ?line A2 = erl_scan:set_attribute(line, A1, F), -    ?line {line,-9} = erl_scan:attributes_info(A2, line), -    ?line {location,{-9,17}} = erl_scan:attributes_info(A2, location), -    ?line [{line,-9},{column,17}] = -        erl_scan:attributes_info(A2, [line,column,text]), - -    F2 = fun(Line) -> {17,Line} end, -    ?line Attr1 = erl_scan:set_attribute(line, 2, F2), -    ?line {line,{17,2}} = erl_scan:attributes_info(Attr1, line), -    ?line undefined = erl_scan:attributes_info(Attr1, column), -    ?line {location,{17,2}} = % a bit mixed up -        erl_scan:attributes_info(Attr1, location), - -    ?line A3 = erl_scan:set_attribute(line, A1, F2), -    ?line {line,{17,9}} = erl_scan:attributes_info(A3, line), -    ?line {location,{{17,9},17}} = erl_scan:attributes_info(A3, location), -    ?line [{line,{17,9}},{column,17}] = -        erl_scan:attributes_info(A3, [line,column,text]), - -    ?line {ok,[{atom,A4,foo}],_} = erl_scan:string("foo", {9,17}, [text]), -    ?line A5 = erl_scan:set_attribute(line, A4, F), -    ?line {line,-9} = erl_scan:attributes_info(A5, line), -    ?line {location,{-9,17}} = erl_scan:attributes_info(A5, location), -    ?line [{line,-9},{column,17},{text,"foo"}] = -        erl_scan:attributes_info(A5, [line,column,text]), - -    ?line {ok,[{atom,A6,foo}],_} = erl_scan:string("foo", 11, [text]), -    ?line A7 = erl_scan:set_attribute(line, A6, F2), -    %% Incompatible with pre 18: -    %% {line,{17,11}} = erl_scan:attributes_info(A7, line), -    {line,17} = erl_scan:attributes_info(A7, line), -    ?line {location,{17,11}} = % mixed up -        erl_scan:attributes_info(A7, location), -    %% Incompatible with pre 18: -    %% [{line,{17,11}},{text,"foo"}] = -    %%   erl_scan:attributes_info(A7, [line,column,text]), -    [{line,17},{column,11},{text,"foo"}] = -        erl_scan:attributes_info(A7, [line,column,text]), - -    ?line {'EXIT',_} = -        (catch {foo, erl_scan:set_attribute(line, [], F2)}), % type error -    ?line {'EXIT',{badarg,_}} = -        (catch {foo, erl_scan:set_attribute(column, [], F2)}), % type error - -    Attr10 = erl_anno:new(8), -    Attr20 = erl_scan:set_attribute(line, Attr10, -                                    fun(L) -> {nos,'X',L} end), -    %% OTP-9412 -    Attr30 = erl_scan:set_attribute(line, Attr20, -                                    fun({nos,_V,VL}) -> VL end), -    8 = erl_anno:to_term(Attr30), -    ok. -  column_errors() ->      ?line {error,{{1,1},erl_scan,{string,$',""}},{1,3}} = % $'          erl_scan:string("'\\",{1,1}), @@ -892,14 +813,13 @@ unicode() ->          erl_scan_string(Qs, 1),      {ok,[Q2],{1,9}} =          erl_scan:string("$\\x{aaa}", {1,1}, [text]), -    [{category,char},{column,1},{length,8}, -           {line,1},{symbol,16#aaa},{text,Qs}] = -        erl_scan:token_info(Q2), +    [{category,char},{column,1},{line,1},{symbol,16#aaa},{text,Qs}] = +        token_info_long(Q2),      U1 = "\"\\x{aaa}\"", -    {ok,[{string,A1,[2730]}],{1,10}} = erl_scan:string(U1, {1,1}, [text]), -    [{line,1},{column,1},{text,"\"\\x{aaa}\""}] = -        erl_scan:attributes_info(A1, [line, column, text]), +    {ok,[{string,_,[2730]}=T1],{1,10}} = erl_scan:string(U1, {1,1}, [text]), +    {1,1} = erl_scan:location(T1), +    "\"\\x{aaa}\"" = erl_scan:text(T1),      {ok,[{string,1,[2730]}],1} = erl_scan_string(U1, 1),      U2 = "\"\\x41\\x{fff}\\x42\"", @@ -1012,16 +932,13 @@ otp_10302(Config) when is_list(Config) ->      Qs = "$\\x{aaa}",      {ok,[{char,1,2730}],1} = erl_scan_string(Qs, 1),      {ok,[Q2],{1,9}} = erl_scan:string(Qs,{1,1},[text]), -    [{category,char},{column,1},{length,8}, -     {line,1},{symbol,16#aaa},{text,Qs}] = -        erl_scan:token_info(Q2), - -    Tags = [category, column, length, line, symbol, text], +    [{category,char},{column,1},{line,1},{symbol,16#aaa},{text,Qs}] = +        token_info_long(Q2),      U1 = "\"\\x{aaa}\"",      {ok,[T1],{1,10}} = erl_scan:string(U1, {1,1}, [text]), -    [{category,string},{column,1},{length,9},{line,1}, -     {symbol,[16#aaa]},{text,U1}] = erl_scan:token_info(T1, Tags), +    [{category,string},{column,1},{line,1},{symbol,[16#aaa]},{text,U1}] = +        token_info_long(T1),      U2 = "\"\\x41\\x{fff}\\x42\"",      {ok,[{string,1,[65,4095,66]}],1} = erl_scan_string(U2, 1), @@ -1353,9 +1270,7 @@ test_wsc([], []) ->      ok;  test_wsc([Token|Tokens], [Token2|Tokens2]) ->      [Text, Text2] = [Text || -                        {text, Text} <- -                            [erl_scan:token_info(T, text) || -                                T <- [Token, Token2]]], +                        Text <- [erl_scan:text(T) || T <- [Token, Token2]]],      Sz = erts_debug:size(Text),      Sz2 = erts_debug:size({Text, Text2}),      IsCompacted = Sz2 < 2*Sz+erts_debug:size({a,a}), @@ -1394,7 +1309,7 @@ all_same(L, Char) ->  newlines_first([]) ->      ok;  newlines_first([Token|Tokens]) -> -    {text,Text} = erl_scan:token_info(Token, text), +    Text = erl_scan:text(Token),      Nnls = length([C || C <- Text, C =:= $\n]),      OK = case Text of               [$\n|_] -> @@ -1414,7 +1329,7 @@ select_tokens(Tokens, Tags) ->      lists:filter(fun(T) -> lists:member(element(1, T), Tags) end, Tokens).  simplify([Token|Tokens]) -> -    {line,Line} = erl_scan:token_info(Token, line), +    Line = erl_scan:line(Token),      [setelement(2, Token, erl_anno:new(Line)) | simplify(Tokens)];  simplify([]) ->      []. @@ -1423,17 +1338,31 @@ get_text(Tokens) ->      lists:flatten(        [T ||            Token <- Tokens, -          ({text,T} = erl_scan:token_info(Token, text)) =/= []]). +          (T = erl_scan:text(Token)) =/= []]).  test_decorated_tokens(String, Tokens) ->      ToksAttrs = token_attrs(Tokens),      test_strings(ToksAttrs, String, 1, 1).  token_attrs(Tokens) -> -    [{L,C,Len,T} || +    [{L,C,length(T),T} ||          Token <- Tokens, -        ([{line,L},{column,C},{length,Len},{text,T}] = -         erl_scan:token_info(Token, [line,column,length,text])) =/= []]. +        ([C,L,T] = token_info(Token)) =/= []]. + +token_info(T) -> +    Column = erl_scan:column(T), +    Line = erl_scan:line(T), +    Text = erl_scan:text(T), +    [Column, Line, Text]. + +token_info_long(T) -> +    Column = erl_scan:column(T), +    Line = erl_scan:line(T), +    Text = erl_scan:text(T), +    Category = erl_scan:category(T), +    Symbol = erl_scan:symbol(T), +    [{category,Category},{column,Column},{line,Line}, +     {symbol,Symbol},{text,Text}].  test_strings([], _S, Line, Column) ->      {Line,Column}; @@ -1514,8 +1443,7 @@ consistent_attributes([Ts | TsL]) ->      L = [T || T <- Ts, is_integer(element(2, T))],      case L of          [] -> -            TagsL = [[Tag || {Tag,_} <- -                                 erl_scan:attributes_info(element(2, T))] || +            TagsL = [[Tag || {Tag,_} <- defined(token_info_long(T))] ||                          T <- Ts],              case lists:usort(TagsL) of                  [_] -> @@ -1531,6 +1459,9 @@ consistent_attributes([Ts | TsL]) ->              Ts      end. +defined(L) -> +    [{T,V} || {T,V} <- L, V =/= undefined]. +  family_list(L) ->      sofs:to_external(family(L)). diff --git a/lib/stdlib/test/ets_SUITE.erl b/lib/stdlib/test/ets_SUITE.erl index ae431d66d9..3e63d19213 100644 --- a/lib/stdlib/test/ets_SUITE.erl +++ b/lib/stdlib/test/ets_SUITE.erl @@ -112,9 +112,8 @@  -define(m(A,B), ?line assert_eq(A,B)).  init_per_testcase(Case, Config) -> -    Seed = {S1,S2,S3} = random:seed0(), %now(), -    random:seed(S1,S2,S3), -    io:format("*** SEED: ~p ***\n", [Seed]), +    rand:seed(exsplus), +    io:format("*** SEED: ~p ***\n", [rand:export_seed()]),      start_spawn_logger(),      wait_for_test_procs(), %% Ensure previous case cleaned up      Dog=test_server:timetrap(test_server:minutes(20)), @@ -731,10 +730,6 @@ chk_normal_tab_struct_size() ->  %       	  ?line ok  %         end. --define(DB_TREE_STACK_NEED,50). % The static stack for a tree, in halfword pointers are two internal words -                                % so the stack gets twice as big --define(DB_HASH_SIZEOF_EXTSEG,260). % The segment size in words, in halfword this will be twice as large. -  adjust_xmem([T1,T2,T3,T4], {A0,B0,C0,D0} = _Mem0) ->      %% Adjust for 64-bit, smp, and os:      %%   Table struct size may differ. @@ -748,19 +743,7 @@ adjust_xmem([T1,T2,T3,T4], {A0,B0,C0,D0} = _Mem0) ->  %          end,      TabDiff = ?TAB_STRUCT_SZ, -    Mem1 = {A0+TabDiff, B0+TabDiff, C0+TabDiff, D0+TabDiff}, - -    case {erlang:system_info({wordsize,internal}),erlang:system_info({wordsize,external})} of -	%% Halfword, corrections for regular pointers occupying two internal words. -	{4,8} -> -	    {A1,B1,C1,D1} = Mem1, -	    {A1+4*ets:info(T1, size)+?DB_TREE_STACK_NEED, -	     B1+3*ets:info(T2, size)+?DB_HASH_SIZEOF_EXTSEG, -	     C1+3*ets:info(T3, size)+?DB_HASH_SIZEOF_EXTSEG, -	     D1+3*ets:info(T4, size)+?DB_HASH_SIZEOF_EXTSEG}; -	_ -> -	    Mem1 -    end. +    {A0+TabDiff, B0+TabDiff, C0+TabDiff, D0+TabDiff}.  t_whitebox(doc) ->      ["Diverse whitebox testes"]; @@ -1346,7 +1329,7 @@ drop_match() ->  ets_match(Tab,Expr) -> -    case random:uniform(2) of +    case rand:uniform(2) of  	1 ->  	    ets:match(Tab,Expr);  	_ -> @@ -1355,14 +1338,14 @@ ets_match(Tab,Expr) ->  match_chunked(Tab,Expr) ->      match_chunked_collect(ets:match(Tab,Expr, -				    random:uniform(1999) + 1)). +				    rand:uniform(1999) + 1)).  match_chunked_collect('$end_of_table') ->      [];  match_chunked_collect({Results, Continuation}) ->      Results ++ match_chunked_collect(ets:match(Continuation)).  ets_match_object(Tab,Expr) -> -    case random:uniform(2) of +    case rand:uniform(2) of  	1 ->  	    ets:match_object(Tab,Expr);  	_ -> @@ -1371,7 +1354,7 @@ ets_match_object(Tab,Expr) ->  match_object_chunked(Tab,Expr) ->      match_object_chunked_collect(ets:match_object(Tab,Expr, -						  random:uniform(1999) + 1)). +						  rand:uniform(1999) + 1)).  match_object_chunked_collect('$end_of_table') ->      [];  match_object_chunked_collect({Results, Continuation}) -> @@ -1383,19 +1366,15 @@ random_test() ->      ?line ReadDir = get(where_to_read),      ?line WriteDir = get(where_to_write),      ?line (catch file:make_dir(WriteDir)), -    ?line Seed = case file:consult(filename:join([ReadDir,  -					    "preset_random_seed.txt"])) of -	       {ok,[X]} -> -		   X; -	       _ -> -		   {A,B,C} = erlang:timestamp(), -		   random:seed(A,B,C), -		   get(random_seed) -	   end, -    put(random_seed,Seed), -    ?line {ok, F} = file:open(filename:join([WriteDir,  -					     "last_random_seed.txt"]),  -			      [write]), +    case file:consult(filename:join([ReadDir,"preset_random_seed.txt"])) of +	{ok,[X]} -> +	    rand:seed(X); +	_ -> +	    rand:seed(exsplus) +    end, +    Seed = rand:export_seed(), +    {ok,F} = file:open(filename:join([WriteDir,"last_random_seed.txt"]), +			[write]),      io:format(F,"~p. ~n",[Seed]),      file:close(F),      io:format("Random seed ~p written to ~s, copy to ~s to rerun with " @@ -1417,7 +1396,7 @@ do_random_test() ->  	       end, 5000),      ?line io:format("~nData inserted~n"),      ?line do_n_times(fun() -> -		       ?line I = random:uniform(25), +		       I = rand:uniform(25),  		       ?line Key = create_random_string(I) ++ '_',  		       ?line L1 = ets_match_object(OrdSet,{Key,'_'}),  		       ?line L2 = lists:sort(ets_match_object(Set,{Key,'_'})), @@ -1977,7 +1956,7 @@ evil_update_counter(Config) when is_list(Config) ->      gb_sets:module_info(),      math:module_info(),      ordsets:module_info(), -    random:module_info(), +    rand:module_info(),      repeat_for_opts(evil_update_counter_do). @@ -2011,7 +1990,7 @@ evil_counter(I,Opts) ->  		1 -> 16#12345678FFFFFFFF;  		2 -> 16#7777777777FFFFFFFF863648726743  	    end, -    Start = Start0 + random:uniform(100000), +    Start = Start0 + rand:uniform(100000),      ets:insert(T, {dracula,Start}),      Iter = 40000,      End = Start + Iter, @@ -4661,11 +4640,11 @@ create_random_string(0) ->      [];  create_random_string(OfLength) -> -    C = case random:uniform(2) of +    C = case rand:uniform(2) of  	1 -> -	    (random:uniform($Z - $A + 1) - 1) + $A; +	    (rand:uniform($Z - $A + 1) - 1) + $A;  	_ -> -	    (random:uniform($z - $a + 1) - 1) + $a +	    (rand:uniform($z - $a + 1) - 1) + $a  	end,      [C | create_random_string(OfLength - 1)]. @@ -4676,7 +4655,7 @@ create_random_tuple(OfLength) ->  			    end,create_random_string(OfLength))).  create_partly_bound_tuple(OfLength) -> -    case random:uniform(2) of +    case rand:uniform(2) of  	1 ->  	   create_partly_bound_tuple1(OfLength);   	_ -> @@ -4685,14 +4664,14 @@ create_partly_bound_tuple(OfLength) ->  create_partly_bound_tuple1(OfLength) ->      T0 = create_random_tuple(OfLength), -    I = random:uniform(OfLength), +    I = rand:uniform(OfLength),      setelement(I,T0,'$1').  set_n_random_elements(T0,0,_,_) ->      T0;  set_n_random_elements(T0,N,OfLength,GenFun) -> -    I = random:uniform(OfLength), +    I = rand:uniform(OfLength),      What = GenFun(I),      case element(I,T0) of  	What -> @@ -4706,12 +4685,12 @@ make_dollar_atom(I) ->      list_to_atom([$$] ++ integer_to_list(I)).  create_partly_bound_tuple2(OfLength) ->      T0 = create_random_tuple(OfLength), -    I = random:uniform(OfLength - 1), +    I = rand:uniform(OfLength - 1),      set_n_random_elements(T0,I,OfLength,fun make_dollar_atom/1).  create_partly_bound_tuple3(OfLength) ->      T0 = create_random_tuple(OfLength), -    I = random:uniform(OfLength - 1), +    I = rand:uniform(OfLength - 1),      set_n_random_elements(T0,I,OfLength,fun(_) -> '_' end).  do_n_times(_,0) -> @@ -5074,11 +5053,12 @@ meta_wb_do(Opts) ->      io:format("Colliding names = ~p\n",[Names]),      F = fun(0,_,_) -> ok; -	   (N,Tabs,Me) -> Name1 = lists:nth(random:uniform(Len),Names),  -			  Name2 = lists:nth(random:uniform(Len),Names),  -			  Op = element(random:uniform(3),OpFuns), -			  NTabs = Op(Name1, Name2, Tabs, Opts), -			  Me(N-1,NTabs,Me)  +	   (N,Tabs,Me) -> +		Name1 = lists:nth(rand:uniform(Len), Names), +		Name2 = lists:nth(rand:uniform(Len), Names), +		Op = element(rand:uniform(3),OpFuns), +		NTabs = Op(Name1, Name2, Tabs, Opts), +		Me(N-1, NTabs, Me)  	end,      F(Len*100, [], F), @@ -5344,7 +5324,7 @@ smp_insert(suite) -> [];  smp_insert(Config) when is_list(Config) ->      ets_new(smp_insert,[named_table,public,{write_concurrency,true}]),      InitF = fun(_) -> ok end, -    ExecF = fun(_) -> true = ets:insert(smp_insert,{random:uniform(10000)}) +    ExecF = fun(_) -> true = ets:insert(smp_insert,{rand:uniform(10000)})  	    end,      FiniF = fun(_) -> ok end,      run_workers(InitF,ExecF,FiniF,100000), @@ -5595,10 +5575,10 @@ smp_select_delete(Config) when is_list(Config) ->      Zeros = erlang:make_tuple(Mod,0),      InitF = fun(_) -> Zeros end,      ExecF = fun(Diffs0) ->  -		    case random:uniform(20) of +		    case rand:uniform(20) of  			1 ->  			    Mod = 17, -			    Eq = random:uniform(Mod) - 1, +			    Eq = rand:uniform(Mod) - 1,  			    Deleted = ets:select_delete(T,  							[{{'_', '$1'},  							  [{'=:=', {'rem', '$1', Mod}, Eq}], @@ -5607,7 +5587,7 @@ smp_select_delete(Config) when is_list(Config) ->  						element(Eq+1,Diffs0) - Deleted),  			    Diffs1;  			_ -> -			    Key = random:uniform(10000), +			    Key = rand:uniform(10000),  			    Eq = Key rem Mod,  			    ?line case ets:insert_new(T,{Key,Key}) of  				      true -> @@ -5811,7 +5791,7 @@ run_workers_do(InitF,ExecF,FiniF,Laps, Exclude) ->  			   N when (N > Exclude) -> N - Exclude  		       end,      io:format("smp starting ~p workers\n",[NumOfProcs]), -    Seeds = [{ProcN,random:uniform(9999)} || ProcN <- lists:seq(1,NumOfProcs)], +    Seeds = [{ProcN,rand:uniform(9999)} || ProcN <- lists:seq(1,NumOfProcs)],      Parent = self(),      Pids = [my_spawn_link(fun()-> worker(Seed,InitF,ExecF,FiniF,Laps,Parent,NumOfProcs) end)  	    || Seed <- Seeds], @@ -5822,7 +5802,7 @@ run_workers_do(InitF,ExecF,FiniF,Laps, Exclude) ->  worker({ProcN,Seed}, InitF, ExecF, FiniF, Laps, Parent, NumOfProcs) ->      io:format("smp worker ~p, seed=~p~n",[self(),Seed]), -    random:seed(Seed,Seed,Seed), +    rand:seed(exsplus, {Seed,Seed,Seed}),      State1 = InitF([ProcN, NumOfProcs]),      State2 = worker_loop(Laps, ExecF, State1),      Result = FiniF(State2), diff --git a/lib/stdlib/test/ets_tough_SUITE.erl b/lib/stdlib/test/ets_tough_SUITE.erl index c6f24fc670..8a7f2b1ec2 100644 --- a/lib/stdlib/test/ets_tough_SUITE.erl +++ b/lib/stdlib/test/ets_tough_SUITE.erl @@ -92,7 +92,7 @@ ex1_sub(Config) ->      ok.  prep(Config) -> -    random:seed(), +    rand:seed(exsplus),      put(dump_ticket,none),      DumpDir = filename:join(?config(priv_dir,Config), "ets_tough"),      file:make_dir(DumpDir), @@ -221,19 +221,19 @@ random_class() ->      random_element(Classes).  random_key() -> -    random:uniform(8). +    rand:uniform(8).  random_value() -> -    case random:uniform(5) of +    case rand:uniform(5) of  	1 -> ok;  	2 -> {data,random_key()};  	3 -> {foo,bar,random_class()}; -	4 -> random:uniform(1000); +	4 -> rand:uniform(1000);  	5 -> {recursive,random_value()}      end.  random_element(T) -> -    I = random:uniform(tuple_size(T)), +    I = rand:uniform(tuple_size(T)),      element(I,T).  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/lib/stdlib/test/filelib_SUITE.erl b/lib/stdlib/test/filelib_SUITE.erl index 01b798faef..c39ff842ee 100644 --- a/lib/stdlib/test/filelib_SUITE.erl +++ b/lib/stdlib/test/filelib_SUITE.erl @@ -318,7 +318,7 @@ same_lists(Expected0, Actual0, BaseDir) ->  mkfiles([H|T], Dir) ->      Name = filename:join(Dir, H), -    Garbage = [31+random:uniform(95) || _ <- lists:seq(1, random:uniform(1024))], +    Garbage = [31+rand:uniform(95) || _ <- lists:seq(1, rand:uniform(1024))],      file:write_file(Name, Garbage),      [Name|mkfiles(T, Dir)];  mkfiles([], _) -> []. diff --git a/lib/stdlib/test/filename_SUITE.erl b/lib/stdlib/test/filename_SUITE.erl index fd47da8150..4372e77df9 100644 --- a/lib/stdlib/test/filename_SUITE.erl +++ b/lib/stdlib/test/filename_SUITE.erl @@ -97,20 +97,11 @@ absname(Config) when is_list(Config) ->  	    ?line file:set_cwd(Cwd),  	    ok; -	Type -> -	    case Type of -		{unix, _} -> -		    ?line ok = file:set_cwd("/usr"), -		    ?line "/usr/foo" = filename:absname(foo), -		    ?line "/usr/foo" = filename:absname("foo"), -		    ?line "/usr/../ebin" = filename:absname("../ebin"); -		{ose, _} -> -		    ?line ok = file:set_cwd("/romfs"), -		    ?line "/romfs/foo" = filename:absname(foo), -		    ?line "/romfs/foo" = filename:absname("foo"), -		    ?line "/romfs/../ebin" = filename:absname("../ebin") -	    end, -	     +	{unix, _} -> +            ?line ok = file:set_cwd("/usr"), +            ?line "/usr/foo" = filename:absname(foo), +            ?line "/usr/foo" = filename:absname("foo"), +            ?line "/usr/../ebin" = filename:absname("../ebin"),  	    ?line file:set_cwd("/"),  	    ?line "/foo" = filename:absname(foo),  	    ?line "/foo" = filename:absname("foo"), @@ -494,18 +485,10 @@ absname_bin(Config) when is_list(Config) ->  	    ?line file:set_cwd(Cwd),  	    ok; -	Type -> -	    case Type of -		{unix,_} -> -		    ?line ok = file:set_cwd(<<"/usr">>), -		    ?line <<"/usr/foo">> = filename:absname(<<"foo">>), -		    ?line <<"/usr/../ebin">> = filename:absname(<<"../ebin">>); -		{ose,_} -> -		    ?line ok = file:set_cwd(<<"/romfs">>), -		    ?line <<"/romfs/foo">> = filename:absname(<<"foo">>), -		    ?line <<"/romfs/../ebin">> = filename:absname(<<"../ebin">>) -	    end, -	     +	{unix, _} -> +            ?line ok = file:set_cwd(<<"/usr">>), +            ?line <<"/usr/foo">> = filename:absname(<<"foo">>), +            ?line <<"/usr/../ebin">> = filename:absname(<<"../ebin">>),  	    ?line file:set_cwd(<<"/">>),  	    ?line <<"/foo">> = filename:absname(<<"foo">>),  	    ?line <<"/../ebin">> = filename:absname(<<"../ebin">>), diff --git a/lib/stdlib/test/lists_SUITE.erl b/lib/stdlib/test/lists_SUITE.erl index a0f7fd2744..bd68c93779 100644 --- a/lib/stdlib/test/lists_SUITE.erl +++ b/lib/stdlib/test/lists_SUITE.erl @@ -1677,8 +1677,7 @@ check_stab(L, U, S, US, SS) ->  %%% Element 3 in the tuple is the position of the tuple in the list.  biglist(N) -> -    {A, B, C} = get_seed(), -    random:seed(A, B, C), +    rand:seed(exsplus),      biglist(N, []).  biglist(0, L) -> @@ -1694,8 +1693,7 @@ biglist(N, L) ->  %%% No sequence number.  ubiglist(N) -> -    {A, B, C} = get_seed(), -    random:seed(A, B, C), +    rand:seed(exsplus),      ubiglist(N, []).  ubiglist(0, L) -> @@ -1719,8 +1717,7 @@ urandom_tuple(N, I) ->  %%% sequence number.  bigfunlist(N) -> -    {A, B, C} = get_seed(), -    random:seed(A, B, C), +    rand:seed(exsplus),      bigfunlist_1(N).  bigfunlist_1(N) when N < 30000 -> % Now (R8) max 32000 different pids. @@ -1754,21 +1751,13 @@ make_fun(Pid) ->  fun_pid(Fun) ->      erlang:fun_info(Fun, pid). -get_seed() -> -    case random:seed() of -	undefined -> -	    erlang:timestamp(); -	Tuple -> -	    Tuple -    end. -  random_tuple(N, Seq) ->      R1 = randint(N),      R2 = randint(N),      {R1, R2, Seq}.  randint(N) -> -    trunc(random:uniform() * N). +    trunc(rand:uniform() * N).  %% The first "duplicate" is kept.  no_dups([]) -> @@ -1830,8 +1819,7 @@ sort_loop_1(Pid) ->      end.  sloop(N) -> -    {A, B, C} = get_seed(), -    random:seed(A, B, C), +    rand:seed(exsplus),      sloop(N, #state{}).  sloop(N, S) -> diff --git a/lib/stdlib/test/queue_SUITE.erl b/lib/stdlib/test/queue_SUITE.erl index c965a8b218..5165ac3a3a 100644 --- a/lib/stdlib/test/queue_SUITE.erl +++ b/lib/stdlib/test/queue_SUITE.erl @@ -470,7 +470,7 @@ oops(suite) ->  oops(Config) when is_list(Config) ->      ?line N = 3142,      ?line Optab = optab(), -    ?line Seed0 = random:seed0(), +    ?line Seed0 = rand:seed(exsplus, {1,2,4}),      ?line {Is,Seed} = random_list(N, tuple_size(Optab), Seed0, []),      ?line io:format("~p ", [Is]),      ?line QA = queue:new(), @@ -562,20 +562,20 @@ args([], _, Seed, R) ->  args([q|Ts], [Q|Qs]=Qss, Seed, R) ->      args(Ts, if Qs =:= [] -> Qss; true -> Qs end, Seed, [Q|R]);  args([l|Ts], Qs, Seed0, R) -> -    {N,Seed1} = random:uniform_s(17, Seed0), +    {N,Seed1} = rand:uniform_s(17, Seed0),      {L,Seed} = random_list(N, 4711, Seed1, []),      args(Ts, Qs, Seed, [L|R]);  args([t|Ts], Qs, Seed0, R) -> -    {T,Seed} = random:uniform_s(4711, Seed0), +    {T,Seed} = rand:uniform_s(4711, Seed0),      args(Ts, Qs, Seed, [T|R]);  args([n|Ts], Qs, Seed0, R) -> -    {N,Seed} = random:uniform_s(17, Seed0), +    {N,Seed} = rand:uniform_s(17, Seed0),      args(Ts, Qs, Seed, [N|R]).  random_list(0, _, Seed, R) ->      {R,Seed};  random_list(N, M, Seed0, R) -> -    {X,Seed} = random:uniform_s(M, Seed0), +    {X,Seed} = rand:uniform_s(M, Seed0),      random_list(N-1, M, Seed, [X|R]).  call(Func, As) -> diff --git a/lib/stdlib/test/random_iolist.erl b/lib/stdlib/test/random_iolist.erl index 9a0f034e72..6da7da04de 100644 --- a/lib/stdlib/test/random_iolist.erl +++ b/lib/stdlib/test/random_iolist.erl @@ -36,7 +36,7 @@ run2(Iter,Fun1,Fun2) ->      compare2(Iter,Fun1,Fun2).  random_byte() -> -     random:uniform(256) - 1. +     rand:uniform(256) - 1.  random_list(0,Acc) ->      Acc; @@ -45,7 +45,7 @@ random_list(N,Acc) ->  random_binary(N) ->      B = list_to_binary(random_list(N,[])), -    case {random:uniform(2),size(B)} of +    case {rand:uniform(2),size(B)} of  	{2,M} when M > 1 ->  	    S = M-1,  	    <<_:3,C:S/binary,_:5>> = B, @@ -57,7 +57,7 @@ random_list(N) ->      random_list(N,[]).  front() -> -    case random:uniform(10) of +    case rand:uniform(10) of  	10 ->  	    false;  	_ -> @@ -65,7 +65,7 @@ front() ->      end.  any_type() -> -    case random:uniform(10) of +    case rand:uniform(10) of  	1 ->  	    list;  	2 -> @@ -77,7 +77,7 @@ any_type() ->      end.  tail_type() -> -    case random:uniform(5) of +    case rand:uniform(5) of  	1 ->  	    list;  	2 -> @@ -90,9 +90,9 @@ random_length(N) ->      UpperLimit = 255,      case N of  	M when M > UpperLimit -> -	    random:uniform(UpperLimit+1) - 1; +	    rand:uniform(UpperLimit+1) - 1;  	_ -> -	    random:uniform(N+1) - 1 +	    rand:uniform(N+1) - 1      end.  random_iolist(0,Acc) -> @@ -139,7 +139,7 @@ random_iolist(N) ->  standard_seed() -> -    random:seed(1201,855653,380975). +    rand:seed(exsplus, {1201,855653,380975}).  do_comp(List,F1,F2) ->      X = F1(List), diff --git a/lib/stdlib/test/random_unicode_list.erl b/lib/stdlib/test/random_unicode_list.erl index ecafe42318..3bc86a8430 100644 --- a/lib/stdlib/test/random_unicode_list.erl +++ b/lib/stdlib/test/random_unicode_list.erl @@ -85,7 +85,7 @@ int_to_utf32_little(I) ->  id(I) -> I.  random_char() -> -     case random:uniform(16#10FFFF+1) - 1 of +     case rand:uniform(16#10FFFF+1) - 1 of  	 X when X >= 16#D800,  	  X =< 16#DFFF ->  	     random_char(); @@ -116,13 +116,13 @@ random_binary(N,Enc) ->  					   int_to(Enc,X)  				   end,  				   L)), -    case {random:uniform(3),size(B)} of +    case {rand:uniform(3),size(B)} of  	{2,M} when M > 1 ->  	    B2 = id(<<1:3,B/binary,1:5>>),  	    <<_:3,C:M/binary,_:5>> = B2,  	    C;  	{3,M} when M > 1 -> -	    X = random:uniform(M+1)-1, +	    X = rand:uniform(M+1)-1,  	    <<B1:X/binary,B2/binary>> = B,  	    [B1,B2];  	_ -> @@ -132,7 +132,7 @@ random_list(N) ->      random_list(N,[]).  front() -> -    case random:uniform(10) of +    case rand:uniform(10) of  	10 ->  	    false;  	_ -> @@ -140,7 +140,7 @@ front() ->      end.  any_type() -> -    case random:uniform(10) of +    case rand:uniform(10) of  	1 ->  	    list;  	2 -> @@ -152,7 +152,7 @@ any_type() ->      end.  tail_type() -> -    case random:uniform(5) of +    case rand:uniform(5) of  	1 ->  	    list;  	2 -> @@ -165,9 +165,9 @@ random_length(N) ->      UpperLimit = 255,      case N of  	M when M > UpperLimit -> -	    random:uniform(UpperLimit+1) - 1; +	    rand:uniform(UpperLimit+1) - 1;  	_ -> -	    random:uniform(N+1) - 1 +	    rand:uniform(N+1) - 1      end.  random_unicode_list(0,Acc,_Enc) -> @@ -214,7 +214,7 @@ random_unicode_list(N,Enc) ->  standard_seed() -> -    random:seed(1201,855653,380975). +    rand:seed(exsplus, {1201,855653,380975}).  do_comp(List,F1,F2) ->      X = F1(List), diff --git a/lib/stdlib/test/run_pcre_tests.erl b/lib/stdlib/test/run_pcre_tests.erl index 1fdc777470..b7d1df39b8 100644 --- a/lib/stdlib/test/run_pcre_tests.erl +++ b/lib/stdlib/test/run_pcre_tests.erl @@ -1083,7 +1083,7 @@ dumponesplit(F,{RE,Line,O,TS}) ->  %% Generate replacement tests from indatafile,   %% you will need perl on the machine  gen_repl_test(OneFile) -> -    random:seed(1219,687731,62804), +    rand:seed(exsplus, {1219,687731,62804}),      {ok,Bin} = file:read_file(OneFile),      Lines = splitfile(0,Bin,1),      Structured = stru(Lines), @@ -1237,15 +1237,15 @@ btr(_) ->  ranchar() -> -    case random:uniform(10) of +    case rand:uniform(10) of  	9 -> $&;          10 -> <<"\\1">>;		   	N when N < 5 -> -	    random:uniform($Z-$A)+$A-1; +	    rand:uniform($Z-$A)+$A-1;  	M when M < 9 -> -	    random:uniform($z-$a)+$a-1 +	    rand:uniform($z-$a)+$a-1      end.  ranstring() -> -    iolist_to_binary([ranchar() || _ <- lists:duplicate(random:uniform(20),0) ]). +    iolist_to_binary([ranchar() || _ <- lists:duplicate(rand:uniform(20),0) ]). diff --git a/lib/stdlib/test/select_SUITE.erl b/lib/stdlib/test/select_SUITE.erl index ead64ffc75..6796676179 100644 --- a/lib/stdlib/test/select_SUITE.erl +++ b/lib/stdlib/test/select_SUITE.erl @@ -212,11 +212,10 @@ init_random(Config) ->  	       {ok,[X]} ->  		   X;  	       _ -> -		   {A,B,C} = erlang:timestamp(), -		   random:seed(A,B,C), -		   get(random_seed) +		   rand:seed(exsplus), +		   rand:export_seed()  	   end, -    put(random_seed,Seed), +    rand:seed(Seed),      {ok, F} = file:open(filename:join([WriteDir, "last_random_seed2.txt"]),   			[write]),      io:format(F,"~p. ~n",[Seed]), @@ -224,11 +223,11 @@ init_random(Config) ->      ok.  create_random_key(N,Type) -> -    gen_key(random:uniform(N),Type). +    gen_key(rand:uniform(N),Type).  create_pb_key(N,list) -> -    X = random:uniform(N), -    case random:uniform(4) of +    X = rand:uniform(N), +    case rand:uniform(4) of  	3 -> {[X, X+1, '_'], fun([Z,Z1,P1]) ->    				      [Z,Z1,P1] =:= [X,X+1,P1] end};  	2 -> {[X, '_', '_'], fun([Z,P1,P2]) ->  [Z,P1,P2] =:= [X,P1,P2] end}; @@ -237,14 +236,14 @@ create_pb_key(N,list) ->  	_ -> {[X, '$1', '$2'], fun([Z,P1,P2]) ->  [Z,P1,P2] =:= [X,P1,P2] end}      end;  create_pb_key(N, tuple) -> -    X = random:uniform(N), -    case random:uniform(2) of +    X = rand:uniform(N), +    case rand:uniform(2) of  	1 -> {{X, X+1, '$1'},fun({Z,Z1,P1}) ->  {Z,Z1,P1} =:= {X,X+1,P1} end};  	_ -> {{X, '$1', '$2'},fun({Z,P1,P2}) ->  {Z,P1,P2} =:= {X,P1,P2} end}      end;  create_pb_key(N, complex) -> -    X = random:uniform(N), -    case random:uniform(2) of +    X = rand:uniform(N), +    case rand:uniform(2) of  	1 -> {{[X, X+1], '$1'}, fun({[Z,Z1],P1}) ->    					{[Z,Z1],P1} =:= {[X,X+1],P1} end};  	_ -> {{[X, '$1'], '$2'},fun({[Z,P1],P2}) ->  diff --git a/lib/stdlib/test/sets_SUITE.erl b/lib/stdlib/test/sets_SUITE.erl index 972a812072..e7fc5595a9 100644 --- a/lib/stdlib/test/sets_SUITE.erl +++ b/lib/stdlib/test/sets_SUITE.erl @@ -107,9 +107,9 @@ add_element_del([H|T], M, S, Del, []) ->      add_element_del(T, M, M(add_element, {H,S}), Del, [H]);  add_element_del([H|T], M, S0, Del, Inserted) ->      S1 = M(add_element, {H,S0}), -    case random:uniform(3) of +    case rand:uniform(3) of  	1 -> -	    OldEl = lists:nth(random:uniform(length(Inserted)), Inserted), +	    OldEl = lists:nth(rand:uniform(length(Inserted)), Inserted),  	    S = M(del_element, {OldEl,S1}),  	    add_element_del(T, M, S, [OldEl|Del], [H|Inserted]);  	_ -> @@ -438,7 +438,7 @@ iterate_1(M) ->      M(empty, []).  iterate_2(M) -> -    random:seed(1, 2, 42), +    rand:seed(exsplus, {1,2,42}),      iter_set(M, 1000).  iter_set(_M, 0) -> @@ -447,7 +447,7 @@ iter_set(M, N) ->      L = [I || I <- lists:seq(1, N)],      T = M(from_list, L),      L = lists:reverse(iterate_set(M, T)), -    R = random:uniform(N), +    R = rand:uniform(N),      S = lists:reverse(iterate_set(M, R, T)),      S = [E || E <- L, E >= R],      iter_set(M, N-1). @@ -481,7 +481,7 @@ sets_mods() ->  test_all(Tester) ->      Res = [begin -	       random:seed(1, 2, 42), +	       rand:seed(exsplus, {1,2,42}),  	       S = Tester(M),  	       {M(size, S),lists:sort(M(to_list, S))}  	   end || M <- sets_mods()], @@ -492,7 +492,7 @@ test_all([{Low,High}|T], Tester) ->  test_all([Sz|T], Tester) when is_integer(Sz) ->      List = rnd_list(Sz),      Res = [begin -		     random:seed(19, 2, Sz), +		     rand:seed(exsplus, {19,2,Sz}),  		     S = Tester(List, M),  		     {M(size, S),lists:sort(M(to_list, S))}  		 end || M <- sets_mods()], @@ -512,10 +512,10 @@ rnd_list(Sz) ->      rnd_list_1(Sz, []).  atomic_rnd_term() -> -    case random:uniform(3) of -	1 -> list_to_atom(integer_to_list($\s+random:uniform(94))++"rnd"); -	2 -> random:uniform(); -	3 -> random:uniform(50)-37 +    case rand:uniform(3) of +	1 -> list_to_atom(integer_to_list($\s+rand:uniform(94))++"rnd"); +	2 -> rand:uniform(); +	3 -> rand:uniform(50)-37      end.  rnd_list_1(0, Acc) -> Acc; @@ -543,7 +543,7 @@ remove_some(List0, P) ->      end.  remove_some([H|T], P, Acc) -> -    case random:uniform() of +    case rand:uniform() of  	F when F < P ->				%Remove.  	    remove_some(T, P, Acc);  	_ -> diff --git a/lib/stdlib/test/timer_SUITE.erl b/lib/stdlib/test/timer_SUITE.erl index 057d82fb65..10dcfad76f 100644 --- a/lib/stdlib/test/timer_SUITE.erl +++ b/lib/stdlib/test/timer_SUITE.erl @@ -80,8 +80,6 @@ report_result(Error) -> ?line test_server:fail(Error).  big_test(N) ->      C = start_collect(),      system_time(), system_time(), system_time(), -    random:seed(erlang:timestamp()), -    random:uniform(100),random:uniform(100),random:uniform(100),      big_loop(C, N, []), @@ -127,17 +125,17 @@ big_loop(C, N, Pids) ->      after 0 ->  	    %% maybe start an interval timer test -	    Pids1 = maybe_start_i_test(Pids, C, random:uniform(4)), +	    Pids1 = maybe_start_i_test(Pids, C, rand:uniform(4)),  	    %% start 1-4 "after" tests -	    Pids2 = start_after_test(Pids1, C, random:uniform(4)), +	    Pids2 = start_after_test(Pids1, C, rand:uniform(4)),  	    %%Pids2=Pids1,  	    %% wait a little while -	    timer:sleep(random:uniform(200)*3), +	    timer:sleep(rand:uniform(200)*3),  	    %% spawn zero, one or two nrev to get some load ;-/ -	    Pids3 = start_nrev(Pids2, random:uniform(100)), +	    Pids3 = start_nrev(Pids2, rand:uniform(100)),  	    big_loop(C, N-1, Pids3)      end. @@ -148,20 +146,20 @@ start_nrev(Pids, N) when N < 25 ->  start_nrev(Pids, N) when N < 75 ->      [spawn_link(timer_SUITE, do_nrev, [1])|Pids];  start_nrev(Pids, _N) -> -    NrevPid1 = spawn_link(timer_SUITE, do_nrev, [random:uniform(1000)*10]), +    NrevPid1 = spawn_link(timer_SUITE, do_nrev, [rand:uniform(1000)*10]),      NrevPid2 = spawn_link(timer_SUITE, do_nrev, [1]),      [NrevPid1,NrevPid2|Pids].  start_after_test(Pids, C, 1) -> -    TO1 = random:uniform(100)*47, +    TO1 = rand:uniform(100)*47,      [s_a_t(C, TO1)|Pids];  start_after_test(Pids, C, 2) -> -    TO1 = random:uniform(100)*47, -    TO2 = TO1 div random:uniform(3) + 101, +    TO1 = rand:uniform(100)*47, +    TO2 = TO1 div rand:uniform(3) + 101,      [s_a_t(C, TO1),s_a_t(C, TO2)|Pids];  start_after_test(Pids, C, N) -> -    TO1 = random:uniform(100)*47, +    TO1 = rand:uniform(100)*47,      start_after_test([s_a_t(C, TO1)|Pids], C, N-1).  s_a_t(C, TimeOut) -> @@ -187,8 +185,8 @@ a_t(C, TimeOut) ->  maybe_start_i_test(Pids, C, 1) ->      %% ok do it -    TOI = random:uniform(53)*49, -    CountI = random:uniform(10) + 3,                      % at least 4 times +    TOI = rand:uniform(53)*49, +    CountI = rand:uniform(10) + 3,		% at least 4 times      [spawn_link(timer_SUITE, i_t, [C, TOI, CountI])|Pids];  maybe_start_i_test(Pids, _C, _) ->      Pids. | 
