diff options
Diffstat (limited to 'lib/stdlib/src')
| -rw-r--r-- | lib/stdlib/src/binary.erl | 8 | ||||
| -rw-r--r-- | lib/stdlib/src/c.erl | 17 | ||||
| -rw-r--r-- | lib/stdlib/src/dict.erl | 6 | ||||
| -rw-r--r-- | lib/stdlib/src/erl_lint.erl | 17 | ||||
| -rw-r--r-- | lib/stdlib/src/erl_tar.erl | 43 | ||||
| -rw-r--r-- | lib/stdlib/src/ets.erl | 23 | ||||
| -rw-r--r-- | lib/stdlib/src/gen_server.erl | 3 | ||||
| -rw-r--r-- | lib/stdlib/src/io_lib.erl | 42 | ||||
| -rw-r--r-- | lib/stdlib/src/io_lib_format.erl | 112 | ||||
| -rw-r--r-- | lib/stdlib/src/math.erl | 7 | ||||
| -rw-r--r-- | lib/stdlib/src/otp_internal.erl | 13 | ||||
| -rw-r--r-- | lib/stdlib/src/string.erl | 46 | ||||
| -rw-r--r-- | lib/stdlib/src/win32reg.erl | 7 | 
13 files changed, 272 insertions, 72 deletions
| diff --git a/lib/stdlib/src/binary.erl b/lib/stdlib/src/binary.erl index b94829892d..de26784ead 100644 --- a/lib/stdlib/src/binary.erl +++ b/lib/stdlib/src/binary.erl @@ -89,9 +89,9 @@ copy(_, _) ->  decode_unsigned(_) ->      erlang:nif_error(undef). --spec decode_unsigned(Subject, Endianess) -> Unsigned when +-spec decode_unsigned(Subject, Endianness) -> Unsigned when        Subject :: binary(), -      Endianess :: big | little, +      Endianness :: big | little,        Unsigned :: non_neg_integer().  decode_unsigned(_, _) -> @@ -103,9 +103,9 @@ decode_unsigned(_, _) ->  encode_unsigned(_) ->      erlang:nif_error(undef). --spec encode_unsigned(Unsigned, Endianess) -> binary() when +-spec encode_unsigned(Unsigned, Endianness) -> binary() when        Unsigned :: non_neg_integer(), -      Endianess :: big | little. +      Endianness :: big | little.  encode_unsigned(_, _) ->      erlang:nif_error(undef). diff --git a/lib/stdlib/src/c.erl b/lib/stdlib/src/c.erl index c2256c0cf9..9860adf04d 100644 --- a/lib/stdlib/src/c.erl +++ b/lib/stdlib/src/c.erl @@ -509,9 +509,12 @@ m(M) ->      {exports,E} = lists:keyfind(exports, 1, L),      Time = get_compile_time(L),      COpts = get_compile_options(L), -    format("Module ~w compiled: ",[M]), print_time(Time), -    format("Compiler options:  ~p~n", [COpts]), +    format("Module: ~w~n", [M]), +    print_md5(L), +    format("Compiled: "), +    print_time(Time),      print_object_file(M), +    format("Compiler options:  ~p~n", [COpts]),      format("Exports: ~n",[]), print_exports(keysort(1, E)).  print_object_file(Mod) -> @@ -522,6 +525,12 @@ print_object_file(Mod) ->  	    ignore      end. +print_md5(L) -> +    case lists:keyfind(md5, 1, L) of +        {md5,<<MD5:128>>} -> io:format("MD5: ~.16b~n",[MD5]); +        _ -> ok +    end. +  get_compile_time(L) ->      case get_compile_info(L, time) of  	{ok,Val} -> Val; @@ -569,8 +578,8 @@ split_print_exports([{F1, A1}|T1], [{F2, A2} | T2]) ->  split_print_exports([], []) -> ok.  print_time({Year,Month,Day,Hour,Min,_Secs}) -> -    format("Date: ~s ~w ~w, ", [month(Month),Day,Year]), -    format("Time: ~.2.0w.~.2.0w~n", [Hour,Min]); +    format("~s ~w ~w, ", [month(Month),Day,Year]), +    format("~.2.0w:~.2.0w~n", [Hour,Min]);  print_time(notime) ->      format("No compile time info available~n",[]). diff --git a/lib/stdlib/src/dict.erl b/lib/stdlib/src/dict.erl index cf8fb3114a..5a9f63c5e2 100644 --- a/lib/stdlib/src/dict.erl +++ b/lib/stdlib/src/dict.erl @@ -417,6 +417,8 @@ on_bucket(F, T, Slot) ->  %%  could have implemented map and filter using fold but these are  %%  faster.  We hope! +fold_dict(F, Acc, #dict{size=0}) when is_function(F, 3) -> +    Acc;  fold_dict(F, Acc, D) ->      Segs = D#dict.segs,      fold_segs(F, Acc, Segs, tuple_size(Segs)). @@ -434,6 +436,8 @@ fold_bucket(F, Acc, [?kv(Key,Val)|Bkt]) ->      fold_bucket(F, F(Key, Val, Acc), Bkt);  fold_bucket(F, Acc, []) when is_function(F, 3) -> Acc. +map_dict(F, #dict{size=0} = Dict) when is_function(F, 2) -> +    Dict;  map_dict(F, D) ->      Segs0 = tuple_to_list(D#dict.segs),      Segs1 = map_seg_list(F, Segs0), @@ -453,6 +457,8 @@ map_bucket(F, [?kv(Key,Val)|Bkt]) ->      [?kv(Key,F(Key, Val))|map_bucket(F, Bkt)];  map_bucket(F, []) when is_function(F, 2) -> []. +filter_dict(F, #dict{size=0} = Dict) when is_function(F, 2) -> +    Dict;  filter_dict(F, D) ->      Segs0 = tuple_to_list(D#dict.segs),      {Segs1,Fc} = filter_seg_list(F, Segs0, [], 0), diff --git a/lib/stdlib/src/erl_lint.erl b/lib/stdlib/src/erl_lint.erl index 26d8454731..cbe6eeec3c 100644 --- a/lib/stdlib/src/erl_lint.erl +++ b/lib/stdlib/src/erl_lint.erl @@ -744,6 +744,8 @@ attribute_state(Form, St) ->  %%      State'  %%  Allow for record, type and opaque type definitions and spec  %%  declarations to be intersperced within function definitions. +%%  Dialyzer attributes are also allowed everywhere, but are not +%%  checked at all.  function_state({attribute,L,record,{Name,Fields}}, St) ->      record_def(L, Name, Fields, St); @@ -753,6 +755,8 @@ function_state({attribute,L,opaque,{TypeName,TypeDef,Args}}, St) ->      type_def(opaque, L, TypeName, TypeDef, Args, St);  function_state({attribute,L,spec,{Fun,Types}}, St) ->      spec_decl(L, Fun, Types, St); +function_state({attribute,_L,dialyzer,_Val}, St) -> +    St;  function_state({attribute,La,Attr,_Val}, St) ->      add_error(La, {attribute,Attr}, St);  function_state({function,L,N,A,Cs}, St) -> @@ -2266,11 +2270,10 @@ expr({remote,Line,_M,_F}, _Vt, St) ->  %%      {UsedVarTable,State}  expr_list(Es, Vt, St) -> -    {Vt1,St1} = foldl(fun (E, {Esvt,St0}) -> -                              {Evt,St1} = expr(E, Vt, St0), -                              {vtmerge_pat(Evt, Esvt),St1} -                      end, {[],St}, Es), -    {vtmerge(vtnew(Vt1, Vt), vtold(Vt1, Vt)),St1}. +    foldl(fun (E, {Esvt,St0}) -> +                  {Evt,St1} = expr(E, Vt, St0), +                  {vtmerge_pat(Evt, Esvt),St1} +          end, {[],St}, Es).  record_expr(Line, Rec, Vt, St0) ->      St1 = warn_invalid_record(Line, Rec, St0), @@ -2288,8 +2291,8 @@ map_fields([{Tag,_,K,V}|Fs], Vt, St, F) when Tag =:= map_field_assoc;      {Pvt,St2} = F([K,V], Vt, St),      {Vts,St3} = map_fields(Fs, Vt, St2, F),      {vtupdate(Pvt, Vts),St3}; -map_fields([], Vt, St, _) -> -  {Vt,St}. +map_fields([], _, St, _) -> +  {[],St}.  %% warn_invalid_record(Line, Record, State0) -> State  %% Adds warning if the record is invalid. diff --git a/lib/stdlib/src/erl_tar.erl b/lib/stdlib/src/erl_tar.erl index ab6223c0fe..caa3276d09 100644 --- a/lib/stdlib/src/erl_tar.erl +++ b/lib/stdlib/src/erl_tar.erl @@ -36,7 +36,7 @@  %% Opens a tar archive.  init(UsrHandle, AccessMode, Fun) when is_function(Fun,2) ->    -    {ok, {AccessMode,{UsrHandle,Fun}}}. +    {ok, {AccessMode,{tar_descriptor,UsrHandle,Fun}}}.  %%%================================================================		     %%% The open function with friends is to keep the file and binary api of this module @@ -532,27 +532,36 @@ read_opts([_|Rest], Opts) ->  read_opts([], Opts) ->      Opts. +foldl_read({AccessMode,TD={tar_descriptor,_UsrHandle,_AccessFun}}, Fun, Accu, Opts) -> +    case AccessMode of +	read -> +	    foldl_read0(TD, Fun, Accu, Opts); +	_ -> +	    {error,{read_mode_expected,AccessMode}} +    end;  foldl_read(TarName, Fun, Accu, Opts) ->      case open(TarName, [read|Opts#read_opts.open_mode]) of  	{ok, {read, File}} -> -	    Result =  -		case catch foldl_read1(Fun, Accu, File, Opts) of -		    {'EXIT', Reason} -> -			exit(Reason); -		    {error, {Reason, Format, Args}} -> -			read_verbose(Opts, Format, Args), -			{error, Reason}; -		    {error, Reason} -> -			{error, Reason}; -		    Ok -> -			Ok -		end, +	    Result = foldl_read0(File, Fun, Accu, Opts),  	    ok = do_close(File),  	    Result;  	Error ->  	    Error      end. +foldl_read0(File, Fun, Accu, Opts) -> +    case catch foldl_read1(Fun, Accu, File, Opts) of +	{'EXIT', Reason} -> +	    exit(Reason); +	{error, {Reason, Format, Args}} -> +	    read_verbose(Opts, Format, Args), +	    {error, Reason}; +	{error, Reason} -> +	    {error, Reason}; +	Ok -> +	    Ok +    end. +  foldl_read1(Fun, Accu0, File, Opts) ->      case get_header(File) of  	eof -> @@ -1014,10 +1023,10 @@ open_mode(_, _, _, _) ->      {error, einval}.  %%%================================================================ -do_write({UsrHandle,Fun}, Data) -> Fun(write,{UsrHandle,Data}). +do_write({tar_descriptor,UsrHandle,Fun}, Data) -> Fun(write,{UsrHandle,Data}). -do_position({UsrHandle,Fun}, Pos) -> Fun(position,{UsrHandle,Pos}). +do_position({tar_descriptor,UsrHandle,Fun}, Pos) -> Fun(position,{UsrHandle,Pos}). -do_read({UsrHandle,Fun}, Len) -> Fun(read2,{UsrHandle,Len}). +do_read({tar_descriptor,UsrHandle,Fun}, Len) -> Fun(read2,{UsrHandle,Len}). -do_close({UsrHandle,Fun}) -> Fun(close,UsrHandle). +do_close({tar_descriptor,UsrHandle,Fun}) -> Fun(close,UsrHandle). diff --git a/lib/stdlib/src/ets.erl b/lib/stdlib/src/ets.erl index 42b11a97e2..09c8924650 100644 --- a/lib/stdlib/src/ets.erl +++ b/lib/stdlib/src/ets.erl @@ -71,6 +71,7 @@           rename/2, safe_fixtable/2, select/1, select/2, select/3,           select_count/2, select_delete/2, select_reverse/1,           select_reverse/2, select_reverse/3, setopts/2, slot/2, +         take/2,           update_counter/3, update_element/3]).  -spec all() -> [Tab] when @@ -133,7 +134,9 @@ give_away(_, _, _) ->                   | {owner, pid()}                   | {protection, access()}                   | {size, non_neg_integer()} -                 | {type, type()}. +                 | {type, type()} +		 | {write_concurrency, boolean()} +		 | {read_concurrency, boolean()}.  info(_) ->      erlang:nif_error(undef). @@ -142,7 +145,8 @@ info(_) ->        Tab :: tab(),        Item :: compressed | fixed | heir | keypos | memory              | name | named_table | node | owner | protection -            | safe_fixed | size | stats | type, +            | safe_fixed | size | stats | type +	    | write_concurrency | read_concurrency,        Value :: term().  info(_, _) -> @@ -400,6 +404,14 @@ setopts(_, _) ->  slot(_, _) ->      erlang:nif_error(undef). +-spec take(Tab, Key) -> [Object] when +      Tab :: tab(), +      Key :: term(), +      Object :: tuple(). + +take(_, _) -> +    erlang:nif_error(undef). +  -spec update_counter(Tab, Key, UpdateOp) -> Result when        Tab :: tab(),        Key :: term(), @@ -1613,13 +1625,18 @@ choice(Height, Width, P, Mode, Tab, Key, Turn, Opos) ->      end.  get_line(P, Default) -> -    case io:get_line(P) of +    case line_string(io:get_line(P)) of  	"\n" ->  	    Default;  	L ->  	    L      end. +%% If the standard input is set to binary mode +%% convert it to a list so we can properly match. +line_string(Binary) when is_binary(Binary) -> unicode:characters_to_list(Binary); +line_string(Other) -> Other. +  nonl(S) -> string:strip(S, right, $\n).  print_number(Tab, Key, Num) -> diff --git a/lib/stdlib/src/gen_server.erl b/lib/stdlib/src/gen_server.erl index 139bf35d27..b29e40e5f7 100644 --- a/lib/stdlib/src/gen_server.erl +++ b/lib/stdlib/src/gen_server.erl @@ -799,8 +799,11 @@ print_event(Dev, Event, Name) ->  %%% Terminate the server.  %%% --------------------------------------------------- +-spec terminate(_, _, _, _, _, _) -> no_return().  terminate(Reason, Name, Msg, Mod, State, Debug) ->      terminate(Reason, Reason, Name, Msg, Mod, State, Debug). + +-spec terminate(_, _, _, _, _, _, _) -> no_return().  terminate(ExitReason, ReportReason, Name, Msg, Mod, State, Debug) ->      Reply = try_terminate(Mod, ExitReason, State),      case Reply of diff --git a/lib/stdlib/src/io_lib.erl b/lib/stdlib/src/io_lib.erl index adc9a0cf5f..e90cda0533 100644 --- a/lib/stdlib/src/io_lib.erl +++ b/lib/stdlib/src/io_lib.erl @@ -1,7 +1,7 @@  %%  %% %CopyrightBegin%  %% -%% Copyright Ericsson AB 1996-2013. All Rights Reserved. +%% Copyright Ericsson AB 1996-2014. All Rights Reserved.  %%  %% The contents of this file are subject to the Erlang Public License,  %% Version 1.1, (the "License"); you may not use this file except in @@ -60,6 +60,7 @@  -module(io_lib).  -export([fwrite/2,fread/2,fread/3,format/2]). +-export([scan_format/2,unscan_format/1,build_text/1]).  -export([print/1,print/4,indentation/2]).  -export([write/1,write/2,write/3,nl/0,format_prompt/1,format_prompt/2]). @@ -83,7 +84,7 @@           deep_unicode_char_list/1]).  -export_type([chars/0, latin1_string/0, continuation/0, -              fread_error/0, fread_item/0]). +              fread_error/0, fread_item/0, format_spec/0]).  %%---------------------------------------------------------------------- @@ -108,6 +109,18 @@  -type fread_item() :: string() | atom() | integer() | float(). +-type format_spec() :: +        #{ +           control_char => char(), +           args         => [any()], +           width        => 'none' | integer(), +           adjust       => 'left' | 'right', +           precision    => 'none' | integer(), +           pad_char     => char(), +           encoding     => 'unicode' | 'latin1', +           strings      => boolean() +         }. +  %%----------------------------------------------------------------------  %% Interface calls to sub-modules. @@ -156,6 +169,31 @@ format(Format, Args) ->  	    Other      end. +-spec scan_format(Format, Data) -> FormatList when +      Format :: io:format(), +      Data :: [term()], +      FormatList :: [char() | format_spec()]. + +scan_format(Format, Args) -> +    try io_lib_format:scan(Format, Args) +    catch +        _:_ -> erlang:error(badarg, [Format, Args]) +    end. + +-spec unscan_format(FormatList) -> {Format, Data} when +      FormatList :: [char() | format_spec()], +      Format :: io:format(), +      Data :: [term()]. + +unscan_format(FormatList) -> +    io_lib_format:unscan(FormatList). + +-spec build_text(FormatList) -> chars() when +      FormatList :: [char() | format_spec()]. + +build_text(FormatList) -> +    io_lib_format:build(FormatList). +  -spec print(Term) -> chars() when        Term :: term(). diff --git a/lib/stdlib/src/io_lib_format.erl b/lib/stdlib/src/io_lib_format.erl index 89ae6fb187..015afb317a 100644 --- a/lib/stdlib/src/io_lib_format.erl +++ b/lib/stdlib/src/io_lib_format.erl @@ -1,7 +1,7 @@  %%  %% %CopyrightBegin%  %%  -%% Copyright Ericsson AB 1996-2013. All Rights Reserved. +%% Copyright Ericsson AB 1996-2014. All Rights Reserved.  %%   %% The contents of this file are subject to the Erlang Public License,  %% Version 1.1, (the "License"); you may not use this file except in @@ -20,10 +20,9 @@  %% Formatting functions of io library. --export([fwrite/2,fwrite_g/1,indentation/2]). +-export([fwrite/2,fwrite_g/1,indentation/2,scan/2,unscan/1,build/1]). -%% fwrite(Format, ArgList) -> string(). -%%  Format the arguments in ArgList after string Format. Just generate +%%  Format the arguments in Args after string Format. Just generate  %%  an error if there is an error in the arguments.  %%  %%  To do the printing command correctly we need to calculate the @@ -37,15 +36,84 @@  %%  and it also splits the handling of the control characters into two  %%  parts. -fwrite(Format, Args) when is_atom(Format) -> -    fwrite(atom_to_list(Format), Args); -fwrite(Format, Args) when is_binary(Format) -> -    fwrite(binary_to_list(Format), Args); +-spec fwrite(Format, Data) -> FormatList when +      Format :: io:format(), +      Data :: [term()], +      FormatList :: [char() | io_lib:format_spec()]. +  fwrite(Format, Args) -> -    Cs = collect(Format, Args), +    build(scan(Format, Args)). + +%% Build the output text for a pre-parsed format list. + +-spec build(FormatList) -> io_lib:chars() when +      FormatList :: [char() | io_lib:format_spec()]. + +build(Cs) ->      Pc = pcount(Cs),      build(Cs, Pc, 0). +%% Parse all control sequences in the format string. + +-spec scan(Format, Data) -> FormatList when +      Format :: io:format(), +      Data :: [term()], +      FormatList :: [char() | io_lib:format_spec()]. + +scan(Format, Args) when is_atom(Format) -> +    scan(atom_to_list(Format), Args); +scan(Format, Args) when is_binary(Format) -> +    scan(binary_to_list(Format), Args); +scan(Format, Args) -> +    collect(Format, Args). + +%% Revert a pre-parsed format list to a plain character list and a +%% list of arguments. + +-spec unscan(FormatList) -> {Format, Data} when +      FormatList :: [char() | io_lib:format_spec()], +      Format :: io:format(), +      Data :: [term()]. + +unscan(Cs) -> +    {print(Cs), args(Cs)}. + +args([#{args := As} | Cs]) -> +    As ++ args(Cs); +args([_C | Cs]) -> +    args(Cs); +args([]) -> +    []. + +print([#{control_char := C, width := F, adjust := Ad, precision := P, +         pad_char := Pad, encoding := Encoding, strings := Strings} | Cs]) -> +    print(C, F, Ad, P, Pad, Encoding, Strings) ++ print(Cs); +print([C | Cs]) -> +    [C | print(Cs)]; +print([]) -> +    []. + +print(C, F, Ad, P, Pad, Encoding, Strings) -> +    [$~] ++ print_field_width(F, Ad) ++ print_precision(P) ++ +        print_pad_char(Pad) ++ print_encoding(Encoding) ++ +        print_strings(Strings) ++ [C]. + +print_field_width(none, _Ad) -> ""; +print_field_width(F, left) -> integer_to_list(-F); +print_field_width(F, right) -> integer_to_list(F). + +print_precision(none) -> ""; +print_precision(P) -> [$. | integer_to_list(P)]. + +print_pad_char($\s) -> ""; % default, no need to make explicit +print_pad_char(Pad) -> [$., Pad]. + +print_encoding(unicode) -> "t"; +print_encoding(latin1) -> "". + +print_strings(false) -> "l"; +print_strings(true) -> "". +  collect([$~|Fmt0], Args0) ->      {C,Fmt1,Args1} = collect_cseq(Fmt0, Args0),      [C|collect(Fmt1, Args1)]; @@ -60,7 +128,10 @@ collect_cseq(Fmt0, Args0) ->      {Encoding,Fmt4,Args4} = encoding(Fmt3, Args3),      {Strings,Fmt5,Args5} = strings(Fmt4, Args4),      {C,As,Fmt6,Args6} = collect_cc(Fmt5, Args5), -    {{C,As,F,Ad,P,Pad,Encoding,Strings},Fmt6,Args6}. +    FormatSpec = #{control_char => C, args => As, width => F, adjust => Ad, +                   precision => P, pad_char => Pad, encoding => Encoding, +                   strings => Strings}, +    {FormatSpec,Fmt6,Args6}.  encoding([$t|Fmt],Args) ->      true = hd(Fmt) =/= $l, @@ -136,17 +207,19 @@ collect_cc([$i|Fmt], [A|Args]) -> {$i,[A],Fmt,Args}.  pcount(Cs) -> pcount(Cs, 0). -pcount([{$p,_As,_F,_Ad,_P,_Pad,_Enc,_Str}|Cs], Acc) -> pcount(Cs, Acc+1); -pcount([{$P,_As,_F,_Ad,_P,_Pad,_Enc,_Str}|Cs], Acc) -> pcount(Cs, Acc+1); +pcount([#{control_char := $p}|Cs], Acc) -> pcount(Cs, Acc+1); +pcount([#{control_char := $P}|Cs], Acc) -> pcount(Cs, Acc+1);  pcount([_|Cs], Acc) -> pcount(Cs, Acc);  pcount([], Acc) -> Acc. -%% build([Control], Pc, Indentation) -> string(). +%% build([Control], Pc, Indentation) -> io_lib:chars().  %%  Interpret the control structures. Count the number of print  %%  remaining and only calculate indentation when necessary. Must also  %%  be smart when calculating indentation for characters in format. -build([{C,As,F,Ad,P,Pad,Enc,Str}|Cs], Pc0, I) -> +build([#{control_char := C, args := As, width := F, adjust := Ad, +         precision := P, pad_char := Pad, encoding := Enc, +         strings := Str} | Cs], Pc0, I) ->      S = control(C, As, F, Ad, P, Pad, Enc, Str, I),      Pc1 = decr_pc(C, Pc0),      if @@ -162,10 +235,14 @@ decr_pc($p, Pc) -> Pc - 1;  decr_pc($P, Pc) -> Pc - 1;  decr_pc(_, Pc) -> Pc. -%% indentation(String, Indentation) -> Indentation. +  %%  Calculate the indentation of the end of a string given its start  %%  indentation. We assume tabs at 8 cols. +-spec indentation(String, StartIndent) -> integer() when +      String :: io_lib:chars(), +      StartIndent :: integer(). +  indentation([$\n|Cs], _I) -> indentation(Cs, 0);  indentation([$\t|Cs], I) -> indentation(Cs, ((I + 8) div 8) * 8);  indentation([C|Cs], I) when is_integer(C) -> @@ -366,7 +443,6 @@ float_data([D|Cs], Ds) when D >= $0, D =< $9 ->  float_data([_|Cs], Ds) ->      float_data(Cs, Ds). -%% fwrite_g(Float)  %%  Writes the shortest, correctly rounded string that converts  %%  to Float when read back with list_to_float/1.  %% @@ -374,6 +450,8 @@ float_data([_|Cs], Ds) ->  %%  in Proceedings of the SIGPLAN '96 Conference on Programming  %%  Language Design and Implementation. +-spec fwrite_g(float()) -> string(). +  fwrite_g(0.0) ->      "0.0";  fwrite_g(Float) when is_float(Float) -> @@ -642,7 +720,7 @@ prefixed_integer(Int, F, Adj, Base, Pad, Prefix, Lowercase)  	    term([Prefix|S], F, Adj, none, Pad)      end. -%% char(Char, Field, Adjust, Precision, PadChar) -> string(). +%% char(Char, Field, Adjust, Precision, PadChar) -> chars().  char(C, none, _Adj, none, _Pad) -> [C];  char(C, F, _Adj, none, _Pad) -> chars(C, F); diff --git a/lib/stdlib/src/math.erl b/lib/stdlib/src/math.erl index 98a70b1644..43f736e54c 100644 --- a/lib/stdlib/src/math.erl +++ b/lib/stdlib/src/math.erl @@ -24,7 +24,7 @@  -export([sin/1, cos/1, tan/1, asin/1, acos/1, atan/1, atan2/2, sinh/1,           cosh/1, tanh/1, asinh/1, acosh/1, atanh/1, exp/1, log/1, -         log10/1, pow/2, sqrt/1, erf/1, erfc/1]). +         log2/1, log10/1, pow/2, sqrt/1, erf/1, erfc/1]).  -spec acos(X) -> float() when        X :: number(). @@ -92,6 +92,11 @@ exp(_) ->  log(_) ->      erlang:nif_error(undef). +-spec log2(X) -> float() when +      X :: number(). +log2(_) -> +    erlang:nif_error(undef). +  -spec log10(X) -> float() when        X :: number().  log10(_) -> diff --git a/lib/stdlib/src/otp_internal.erl b/lib/stdlib/src/otp_internal.erl index 0ace87ef5c..4a338798d0 100644 --- a/lib/stdlib/src/otp_internal.erl +++ b/lib/stdlib/src/otp_internal.erl @@ -578,6 +578,19 @@ obsolete_1(asn1rt, utf8_binary_to_list, 1) ->  obsolete_1(asn1rt, utf8_list_to_binary, 1) ->      {deprecated,{unicode,characters_to_binary,1}}; +%% Added in OTP 18. +obsolete_1(core_lib, get_anno, 1) -> +    {deprecated,{cerl,get_ann,1}}; +obsolete_1(core_lib, set_anno, 2) -> +    {deprecated,{cerl,set_ann,2}}; +obsolete_1(core_lib, is_literal, 1) -> +    {deprecated,{cerl,is_literal,1}}; +obsolete_1(core_lib, is_literal_list, 1) -> +    {deprecated,"deprecated; use lists:all(fun cerl:is_literal/1, L)" +     " instead"}; +obsolete_1(core_lib, literal_value, 1) -> +    {deprecated,{core_lib,concrete,1}}; +  obsolete_1(_, _, _) ->      no. diff --git a/lib/stdlib/src/string.erl b/lib/stdlib/src/string.erl index f9b083a56d..f6903d1c3d 100644 --- a/lib/stdlib/src/string.erl +++ b/lib/stdlib/src/string.erl @@ -221,23 +221,47 @@ substr2([_|String], S) -> substr2(String, S-1).        Tokens :: [Token :: nonempty_string()].  tokens(S, Seps) -> -    tokens1(S, Seps, []). +    case Seps of +	[] -> +	    case S of +		[] -> []; +		[_|_] -> [S] +	    end; +	[C] -> +	    tokens_single_1(reverse(S), C, []); +	[_|_] -> +	    tokens_multiple_1(reverse(S), Seps, []) +    end. -tokens1([C|S], Seps, Toks) -> +tokens_single_1([Sep|S], Sep, Toks) -> +    tokens_single_1(S, Sep, Toks); +tokens_single_1([C|S], Sep, Toks) -> +    tokens_single_2(S, Sep, Toks, [C]); +tokens_single_1([], _, Toks) -> +    Toks. + +tokens_single_2([Sep|S], Sep, Toks, Tok) -> +    tokens_single_1(S, Sep, [Tok|Toks]); +tokens_single_2([C|S], Sep, Toks, Tok) -> +    tokens_single_2(S, Sep, Toks, [C|Tok]); +tokens_single_2([], _Sep, Toks, Tok) -> +    [Tok|Toks]. + +tokens_multiple_1([C|S], Seps, Toks) ->      case member(C, Seps) of -	true -> tokens1(S, Seps, Toks); -	false -> tokens2(S, Seps, Toks, [C]) +	true -> tokens_multiple_1(S, Seps, Toks); +	false -> tokens_multiple_2(S, Seps, Toks, [C])      end; -tokens1([], _Seps, Toks) -> -    reverse(Toks). +tokens_multiple_1([], _Seps, Toks) -> +    Toks. -tokens2([C|S], Seps, Toks, Cs) -> +tokens_multiple_2([C|S], Seps, Toks, Tok) ->      case member(C, Seps) of -	true -> tokens1(S, Seps, [reverse(Cs)|Toks]); -	false -> tokens2(S, Seps, Toks, [C|Cs]) +	true -> tokens_multiple_1(S, Seps, [Tok|Toks]); +	false -> tokens_multiple_2(S, Seps, Toks, [C|Tok])      end; -tokens2([], _Seps, Toks, Cs) -> -    reverse([reverse(Cs)|Toks]). +tokens_multiple_2([], _Seps, Toks, Tok) -> +    [Tok|Toks].  -spec chars(Character, Number) -> String when        Character :: char(), diff --git a/lib/stdlib/src/win32reg.erl b/lib/stdlib/src/win32reg.erl index 48a7e262be..38c41a5f6e 100644 --- a/lib/stdlib/src/win32reg.erl +++ b/lib/stdlib/src/win32reg.erl @@ -218,12 +218,7 @@ expand([C|Rest], [], Result) ->      expand(Rest, [], [C|Result]);  expand([$%|Rest], Env0, Result) ->      Env = lists:reverse(Env0), -    case os:getenv(Env) of -	false -> -	    expand(Rest, [], Result); -	Value -> -	    expand(Rest, [], lists:reverse(Value)++Result) -    end; +    expand(Rest, [], lists:reverse(os:getenv(Env, ""))++Result);  expand([C|Rest], Env, Result) ->      expand(Rest, [C|Env], Result);  expand([], [], Result) -> | 
