diff options
Diffstat (limited to 'lib/stdlib/src')
-rw-r--r-- | lib/stdlib/src/calendar.erl | 94 | ||||
-rw-r--r-- | lib/stdlib/src/erl_pp.erl | 4 | ||||
-rw-r--r-- | lib/stdlib/src/gen_statem.erl | 40 | ||||
-rw-r--r-- | lib/stdlib/src/io_lib.erl | 18 | ||||
-rw-r--r-- | lib/stdlib/src/io_lib_format.erl | 27 | ||||
-rw-r--r-- | lib/stdlib/src/io_lib_pretty.erl | 64 | ||||
-rw-r--r-- | lib/stdlib/src/otp_internal.erl | 15 | ||||
-rw-r--r-- | lib/stdlib/src/slave.erl | 17 | ||||
-rw-r--r-- | lib/stdlib/src/stdlib.appup.src | 10 | ||||
-rw-r--r-- | lib/stdlib/src/sys.erl | 28 |
10 files changed, 213 insertions, 104 deletions
diff --git a/lib/stdlib/src/calendar.erl b/lib/stdlib/src/calendar.erl index bb5d450cd6..3a8fe2211b 100644 --- a/lib/stdlib/src/calendar.erl +++ b/lib/stdlib/src/calendar.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2018. All Rights Reserved. +%% Copyright Ericsson AB 1996-2019. 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. @@ -357,13 +357,17 @@ rfc3339_to_system_time(DateTimeString) -> rfc3339_to_system_time(DateTimeString, Options) -> Unit = proplists:get_value(unit, Options, second), %% _T is the character separating the date and the time: - {DateStr, [_T|TimeStr]} = lists:split(10, DateTimeString), - {TimeStr2, TimeStr3} = lists:split(8, TimeStr), - {ok, [Hour, Min, Sec], []} = io_lib:fread("~d:~d:~d", TimeStr2), - {ok, [Year, Month, Day], []} = io_lib:fread("~d-~d-~d", DateStr), + [Y1, Y2, Y3, Y4, $-, Mon1, Mon2, $-, D1, D2, _T, + H1, H2, $:, Min1, Min2, $:, S1, S2 | TimeStr] = DateTimeString, + Hour = list_to_integer([H1, H2]), + Min = list_to_integer([Min1, Min2]), + Sec = list_to_integer([S1, S2]), + Year = list_to_integer([Y1, Y2, Y3, Y4]), + Month = list_to_integer([Mon1, Mon2]), + Day = list_to_integer([D1, D2]), DateTime = {{Year, Month, Day}, {Hour, Min, Sec}}, IsFractionChar = fun(C) -> C >= $0 andalso C =< $9 orelse C =:= $. end, - {FractionStr, UtcOffset} = lists:splitwith(IsFractionChar, TimeStr3), + {FractionStr, UtcOffset} = lists:splitwith(IsFractionChar, TimeStr), Time = datetime_to_system_time(DateTime), Secs = Time - offset_adjustment(Time, second, UtcOffset), check(DateTimeString, Options, Secs), @@ -451,8 +455,9 @@ system_time_to_rfc3339(Time, Options) -> DateTime = system_time_to_datetime(Secs), {{Year, Month, Day}, {Hour, Min, Sec}} = DateTime, FractionStr = fraction_str(Factor, AdjustedTime), - flat_fwrite("~4.10.0B-~2.10.0B-~2.10.0B~c~2.10.0B:~2.10.0B:~2.10.0B~s~s", - [Year, Month, Day, T, Hour, Min, Sec, FractionStr, Offset]). + L = [pad4(Year), "-", pad2(Month), "-", pad2(Day), [T], + pad2(Hour), ":", pad2(Min), ":", pad2(Sec), FractionStr, Offset], + lists:append(L). %% time_difference(T1, T2) = Tdiff %% @@ -529,24 +534,41 @@ valid_date({Y, M, D}) -> %% day_to_year(DayOfEpoch) = {Year, DayOfYear} %% -%% The idea here is to first guess a year, and then adjust. Although -%% the implementation is recursive, at most 1 or 2 recursive steps +%% The idea here is to first set the upper and lower bounds for a year, +%% and then adjust a range by interpolation search. Although complexity +%% of the algorithm is log(log(n)), at most 1 or 2 recursive steps %% are taken. -%% If DayOfEpoch is very large, we need far more than 1 or 2 iterations, -%% since we just subtract a yearful of days at a time until we're there. %% -spec day_to_year(non_neg_integer()) -> {year(), day_of_year()}. day_to_year(DayOfEpoch) when DayOfEpoch >= 0 -> - Y0 = DayOfEpoch div ?DAYS_PER_YEAR, - {Y1, D1} = dty(Y0, DayOfEpoch, dy(Y0)), + YMax = DayOfEpoch div ?DAYS_PER_YEAR, + YMin = DayOfEpoch div ?DAYS_PER_LEAP_YEAR, + {Y1, D1} = dty(YMin, YMax, DayOfEpoch, dy(YMin), dy(YMax)), {Y1, DayOfEpoch - D1}. --spec dty(year(), non_neg_integer(), non_neg_integer()) -> +-spec dty(year(), year(), non_neg_integer(), non_neg_integer(), + non_neg_integer()) -> {year(), non_neg_integer()}. -dty(Y, D1, D2) when D1 < D2 -> - dty(Y-1, D1, dy(Y-1)); -dty(Y, _D1, D2) -> - {Y, D2}. +dty(Min, Max, _D1, DMin, _DMax) when Min == Max -> + {Min, DMin}; +dty(Min, Max, D1, DMin, DMax) -> + Diff = Max - Min, + Mid = Min + (Diff * (D1 - DMin)) div (DMax - DMin), + MidLength = + case is_leap_year(Mid) of + true -> ?DAYS_PER_LEAP_YEAR; + false -> ?DAYS_PER_YEAR + end, + case dy(Mid) of + D2 when D1 < D2 -> + NewMax = Mid - 1, + dty(Min, NewMax, D1, DMin, dy(NewMax)); + D2 when D1 - D2 >= MidLength -> + NewMin = Mid + 1, + dty(NewMin, Max, D1, dy(NewMin), DMax); + D2 -> + {Mid, D2} + end. %% %% The Gregorian days of the iso week 01 day 1 for a given year. @@ -663,7 +685,7 @@ offset(OffsetOption, Secs0) when OffsetOption =:= ""; Secs = abs(Secs0), Hour = Secs div 3600, Min = (Secs rem 3600) div 60, - io_lib:fwrite("~c~2.10.0B:~2.10.0B", [Sign, Hour, Min]); + [Sign | lists:append([pad2(Hour), ":", pad2(Min)])]; offset(OffsetOption, _Secs) -> OffsetOption. @@ -678,8 +700,10 @@ offset_string_adjustment(_Time, _Unit, "Z") -> 0; offset_string_adjustment(_Time, _Unit, "z") -> 0; -offset_string_adjustment(_Time, _Unit, [Sign|Tz]) -> - {ok, [Hour, Min], []} = io_lib:fread("~d:~d", Tz), +offset_string_adjustment(_Time, _Unit, Tz) -> + [Sign, H1, H2, $:, M1, M2] = Tz, + Hour = list_to_integer([H1, H2]), + Min = list_to_integer([M1, M2]), Adjustment = 3600 * Hour + 60 * Min, case Sign of $- -> -Adjustment; @@ -687,8 +711,9 @@ offset_string_adjustment(_Time, _Unit, [Sign|Tz]) -> end. local_offset(SystemTime, Unit) -> - LocalTime = system_time_to_local_time(SystemTime, Unit), + %% Not optimized for special cases. UniversalTime = system_time_to_universal_time(SystemTime, Unit), + LocalTime = erlang:universaltime_to_localtime(UniversalTime), LocalSecs = datetime_to_gregorian_seconds(LocalTime), UniversalSecs = datetime_to_gregorian_seconds(UniversalTime), LocalSecs - UniversalSecs. @@ -697,7 +722,8 @@ fraction_str(1, _Time) -> ""; fraction_str(Factor, Time) -> Fraction = Time rem Factor, - io_lib:fwrite(".~*..0B", [log10(Factor), abs(Fraction)]). + S = integer_to_list(abs(Fraction)), + [$. | pad(log10(Factor) - length(S), S)]. fraction(second, _) -> 0; @@ -718,5 +744,21 @@ log10(1000) -> 3; log10(1000000) -> 6; log10(1000000000) -> 9. -flat_fwrite(F, S) -> - lists:flatten(io_lib:fwrite(F, S)). +pad(0, S) -> + S; +pad(I, S) -> + [$0 | pad(I - 1, S)]. + +pad2(N) when N < 10 -> + [$0 | integer_to_list(N)]; +pad2(N) -> + integer_to_list(N). + +pad4(N) when N < 10 -> + [$0, $0, $0 | integer_to_list(N)]; +pad4(N) when N < 100 -> + [$0, $0 | integer_to_list(N)]; +pad4(N) when N < 1000 -> + [$0 | integer_to_list(N)]; +pad4(N) -> + integer_to_list(N). diff --git a/lib/stdlib/src/erl_pp.erl b/lib/stdlib/src/erl_pp.erl index dd302a2880..ada3ff5de3 100644 --- a/lib/stdlib/src/erl_pp.erl +++ b/lib/stdlib/src/erl_pp.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2018. All Rights Reserved. +%% Copyright Ericsson AB 1996-2019. 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. @@ -697,6 +697,8 @@ fun_info(Extra) -> %% BITS: +bit_grp([], _Opts) -> + leaf("<<>>"); bit_grp(Fs, Opts) -> append([['<<'], [bit_elems(Fs, Opts)], ['>>']]). diff --git a/lib/stdlib/src/gen_statem.erl b/lib/stdlib/src/gen_statem.erl index 513118a874..49911eac2c 100644 --- a/lib/stdlib/src/gen_statem.erl +++ b/lib/stdlib/src/gen_statem.erl @@ -67,6 +67,14 @@ %% Type that is exported just to be documented -export_type([transition_option/0]). +%% Type exports for start_link & friends +-export_type( + [server_name/0, + server_ref/0, + start_opt/0, + start_ret/0, + enter_loop_opt/0]). + %%%========================================================================== %%% Interface functions. %%%========================================================================== @@ -424,28 +432,26 @@ timeout_event_type(Type) -> %%% API -type server_name() :: - {'global', GlobalName :: term()} + {'global', GlobalName :: term()} | {'via', RegMod :: module(), Name :: term()} | {'local', atom()}. -type server_ref() :: - pid() + pid() | (LocalName :: atom()) | {Name :: atom(), Node :: atom()} | {'global', GlobalName :: term()} | {'via', RegMod :: module(), ViaName :: term()}. --type debug_opt() :: - {'debug', - Dbgs :: - ['trace' | 'log' | 'statistics' | 'debug' - | {'logfile', string()}]}. --type hibernate_after_opt() :: - {'hibernate_after', HibernateAfterTimeout :: timeout()}. -type start_opt() :: - debug_opt() - | {'timeout', Time :: timeout()} - | hibernate_after_opt() - | {'spawn_opt', [proc_lib:spawn_option()]}. --type start_ret() :: {'ok', pid()} | 'ignore' | {'error', term()}. + {'timeout', Time :: timeout()} + | {'spawn_opt', [proc_lib:spawn_option()]} + | enter_loop_opt(). +-type start_ret() :: + {'ok', pid()} + | 'ignore' + | {'error', term()}. +-type enter_loop_opt() :: + {'hibernate_after', HibernateAfterTimeout :: timeout()} + | {'debug', Dbgs :: [sys:debug_option()]}. @@ -558,14 +564,14 @@ reply({To,Tag}, Reply) when is_pid(To) -> %% started by proc_lib into a state machine using %% the same arguments as you would have returned from init/1 -spec enter_loop( - Module :: module(), Opts :: [debug_opt() | hibernate_after_opt()], + Module :: module(), Opts :: [enter_loop_opt()], State :: state(), Data :: data()) -> no_return(). enter_loop(Module, Opts, State, Data) -> enter_loop(Module, Opts, State, Data, self()). %% -spec enter_loop( - Module :: module(), Opts :: [debug_opt() | hibernate_after_opt()], + Module :: module(), Opts :: [enter_loop_opt()], State :: state(), Data :: data(), Server_or_Actions :: server_name() | pid() | [action()]) -> @@ -579,7 +585,7 @@ enter_loop(Module, Opts, State, Data, Server_or_Actions) -> end. %% -spec enter_loop( - Module :: module(), Opts :: [debug_opt() | hibernate_after_opt()], + Module :: module(), Opts :: [enter_loop_opt()], State :: state(), Data :: data(), Server :: server_name() | pid(), Actions :: [action()] | action()) -> diff --git a/lib/stdlib/src/io_lib.erl b/lib/stdlib/src/io_lib.erl index 8223a52873..2b5a374cf2 100644 --- a/lib/stdlib/src/io_lib.erl +++ b/lib/stdlib/src/io_lib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2018. All Rights Reserved. +%% Copyright Ericsson AB 1996-2019. 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. @@ -87,6 +87,8 @@ -export([limit_term/2]). +-export([chars_length/1]). + -export_type([chars/0, latin1_string/0, continuation/0, fread_error/0, fread_item/0, format_spec/0, chars_limit/0]). @@ -1131,3 +1133,17 @@ test_limit_map_assoc(K, V, D) -> test_limit(V, D - 1). test_limit_bitstring(_, _) -> ok. + +-spec chars_length(chars()) -> non_neg_integer(). +%% Optimized for deep lists S such that deep_latin1_char_list(S) is +%% true. No binaries allowed! It is assumed that $\r is never followed +%% by $\n if S is an iolist() (string:length() assigns such a +%% sub-sequence length 1). +chars_length(S) -> + try + %% true = deep_latin1_char_list(S), + iolist_size(S) + catch + _:_ -> + string:length(S) + end. diff --git a/lib/stdlib/src/io_lib_format.erl b/lib/stdlib/src/io_lib_format.erl index ab9031573b..d1aa4cd157 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-2018. All Rights Reserved. +%% Copyright Ericsson AB 1996-2019. 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. @@ -248,7 +248,7 @@ count_small([#{control_char := $s}|Cs], #{w := W} = Cnts) -> count_small(Cs, Cnts#{w := W + 1}); count_small([S|Cs], #{other := Other} = Cnts) when is_list(S); is_binary(S) -> - count_small(Cs, Cnts#{other := Other + string:length(S)}); + count_small(Cs, Cnts#{other := Other + io_lib:chars_length(S)}); count_small([C|Cs], #{other := Other} = Cnts) when is_integer(C) -> count_small(Cs, Cnts#{other := Other + 1}); count_small([], #{p := P, s := S, w := W, other := Other}) -> @@ -280,10 +280,15 @@ build_limited([#{control_char := C, args := As, width := F, adjust := Ad, true -> MaxLen0 div Count0 end, S = control_limited(C, As, F, Ad, P, Pad, Enc, Str, MaxChars, I), - Len = string:length(S), NumOfPs = decr_pc(C, NumOfPs0), Count = Count0 - 1, - MaxLen = sub(MaxLen0, Len), + MaxLen = if + MaxLen0 < 0 -> % optimization + MaxLen0; + true -> + Len = io_lib:chars_length(S), + sub(MaxLen0, Len) + end, if NumOfPs > 0 -> [S|build_limited(Cs, NumOfPs, Count, MaxLen, indentation(S, I))]; @@ -406,7 +411,7 @@ base(B) when is_integer(B) -> term(T, none, _Adj, none, _Pad) -> T; term(T, none, Adj, P, Pad) -> term(T, P, Adj, P, Pad); term(T, F, Adj, P0, Pad) -> - L = string:length(T), + L = io_lib:chars_length(T), P = erlang:min(L, case P0 of none -> F; _ -> min(P0, F) end), if L > P -> @@ -713,7 +718,7 @@ fwrite_g(Fl, F, Adj, P, Pad) when P >= 1 -> end. -%% iolist_to_chars(iolist()) -> deep_char_list() +%% iolist_to_chars(iolist()) -> io_lib:chars() iolist_to_chars([C|Cs]) when is_integer(C), C >= $\000, C =< $\377 -> [C | iolist_to_chars(Cs)]; @@ -729,7 +734,7 @@ iolist_to_chars(B) when is_binary(B) -> %% cbinary() | nil()) %% cbinary() :: unicode:unicode_binary() | unicode:latin1_binary() -%% cdata_to_chars(cdata()) -> io_lib:deep_char_list() +%% cdata_to_chars(cdata()) -> io_lib:chars() cdata_to_chars([C|Cs]) when is_integer(C), C >= $\000 -> [C | cdata_to_chars(Cs)]; @@ -745,7 +750,7 @@ cdata_to_chars(B) when is_binary(B) -> limit_string(S, F, CharsLimit) when CharsLimit < 0; CharsLimit >= F -> S; limit_string(S, _F, CharsLimit) -> - case string:length(S) =< CharsLimit of + case io_lib:chars_length(S) =< CharsLimit of true -> S; false -> [string:slice(S, 0, sub(CharsLimit, 3)), "..."] end. @@ -759,11 +764,11 @@ limit_field(F, CharsLimit) -> string(S, none, _Adj, none, _Pad) -> S; string(S, F, Adj, none, Pad) -> - string_field(S, F, Adj, string:length(S), Pad); + string_field(S, F, Adj, io_lib:chars_length(S), Pad); string(S, none, _Adj, P, Pad) -> - string_field(S, P, left, string:length(S), Pad); + string_field(S, P, left, io_lib:chars_length(S), Pad); string(S, F, Adj, P, Pad) when F >= P -> - N = string:length(S), + N = io_lib:chars_length(S), if F > P -> if N > P -> adjust(flat_trunc(S, P), chars(Pad, F-P), Adj); diff --git a/lib/stdlib/src/io_lib_pretty.erl b/lib/stdlib/src/io_lib_pretty.erl index ba9d9e8434..8f2fd7ea8f 100644 --- a/lib/stdlib/src/io_lib_pretty.erl +++ b/lib/stdlib/src/io_lib_pretty.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2018. All Rights Reserved. +%% Copyright Ericsson AB 1996-2019. 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. @@ -507,20 +507,20 @@ print_length(#{}=M, _D, _T, _RF, _Enc, _Str) when map_size(M) =:= 0 -> {"#{}", 3, 0, no_more}; print_length(Atom, _D, _T, _RF, Enc, _Str) when is_atom(Atom) -> S = write_atom(Atom, Enc), - {S, string:length(S), 0, no_more}; + {S, io_lib:chars_length(S), 0, no_more}; print_length(List, D, T, RF, Enc, Str) when is_list(List) -> %% only flat lists are "printable" case Str andalso printable_list(List, D, T, Enc) of true -> %% print as string, escaping double-quotes in the list S = write_string(List, Enc), - {S, string:length(S), 0, no_more}; + {S, io_lib:chars_length(S), 0, no_more}; {true, Prefix} -> %% Truncated lists when T < 0 could break some existing code. S = write_string(Prefix, Enc), %% NumOfDots = 0 to avoid looping--increasing the depth %% does not make Prefix longer. - {[S | "..."], 3 + string:length(S), 0, no_more}; + {[S | "..."], 3 + io_lib:chars_length(S), 0, no_more}; false -> case print_length_list(List, D, T, RF, Enc, Str) of {What, Len, Dots, _More} when Dots > 0 -> @@ -564,7 +564,7 @@ print_length(<<_/bitstring>> = Bin, D, T, RF, Enc, Str) -> {[$<,$<,S,$>,$>], 4 + length(S), 0, no_more}; {false, List} when is_list(List) -> S = io_lib:write_string(List, $"), %" - {[$<,$<,S,"/utf8>>"], 9 + string:length(S), 0, no_more}; + {[$<,$<,S,"/utf8>>"], 9 + io_lib:chars_length(S), 0, no_more}; {true, true, Prefix} -> S = io_lib:write_string(Prefix, $"), %" More = fun(T1, Dd) -> @@ -576,7 +576,7 @@ print_length(<<_/bitstring>> = Bin, D, T, RF, Enc, Str) -> More = fun(T1, Dd) -> ?FUNCTION_NAME(Bin, D+Dd, T1, RF, Enc, Str) end, - {[$<,$<,S|"/utf8...>>"], 12 + string:length(S), 3, More}; + {[$<,$<,S|"/utf8...>>"], 12 + io_lib:chars_length(S), 3, More}; false -> case io_lib:write_binary(Bin, D, T) of {S, <<>>} -> @@ -591,7 +591,7 @@ print_length(<<_/bitstring>> = Bin, D, T, RF, Enc, Str) -> print_length(Term, _D, _T, _RF, _Enc, _Str) -> S = io_lib:write(Term), %% S can contain unicode, so iolist_size(S) cannot be used here - {S, string:length(S), 0, no_more}. + {S, io_lib:chars_length(S), 0, no_more}. print_length_map(Map, 1, _T, RF, Enc, Str) -> More = fun(T1, Dd) -> ?FUNCTION_NAME(Map, 1+Dd, T1, RF, Enc, Str) end, @@ -651,7 +651,7 @@ print_length_record(Tuple, 1, _T, RF, RDefs, Enc, Str) -> {"{...}", 5, 3, More}; print_length_record(Tuple, D, T, RF, RDefs, Enc, Str) -> Name = [$# | write_atom(element(1, Tuple), Enc)], - NameL = string:length(Name), + NameL = io_lib:chars_length(Name), T1 = tsub(T, NameL+2), L = print_length_fields(RDefs, D - 1, T1, Tuple, 2, RF, Enc, Str), {Len, Dots} = list_length(L, NameL + 2, 0), @@ -677,7 +677,7 @@ print_length_fields([Def | Defs], D, T, Tuple, I, RF, Enc, Str) -> print_length_field(Def, D, T, E, RF, Enc, Str) -> Name = write_atom(Def, Enc), - NameL = string:length(Name) + 3, + NameL = io_lib:chars_length(Name) + 3, {_, Len, Dots, _} = Field = print_length(E, D, tsub(T, NameL), RF, Enc, Str), {{field, Name, NameL, Field}, NameL + Len, Dots, no_more}. @@ -721,7 +721,7 @@ printable_list(_L, 1, _T, _Enc) -> printable_list(L, _D, T, latin1) when T < 0 -> io_lib:printable_latin1_list(L); printable_list(L, _D, T, Enc) when T >= 0 -> - case slice(L, tsub(T, 2)) of + case slice(L, tsub(T, 2), Enc) of false -> false; {prefix, Prefix} when Enc =:= latin1 -> @@ -737,20 +737,46 @@ printable_list(L, _D, T, Enc) when T >= 0 -> printable_list(L, _D, T, _Uni) when T < 0-> io_lib:printable_list(L). -slice(L, N) -> - try string:length(L) =< N of - true -> +slice(L, N, latin1) -> + try lists:split(N, L) of + {_, []} -> all; - false -> - case string:slice(L, 0, N) of - "" -> - false; - Prefix -> - {prefix, Prefix} + {[], _} -> + false; + {L1, _} -> + {prefix, L1} + catch + _:_ -> + all + end; +slice(L, N, _Uni) -> + %% Be careful not to traverse more of L than necessary. + try string:slice(L, 0, N) of + "" -> + false; + Prefix -> + %% Assume no binaries are introduced by string:slice(). + case is_flat(L, lists:flatlength(Prefix)) of + true -> + case string:equal(Prefix, L) of + true -> + all; + false -> + {prefix, Prefix} + end; + false -> + false end catch _:_ -> false end. +is_flat(_L, 0) -> + true; +is_flat([C|Cs], N) when is_integer(C) -> + is_flat(Cs, N - 1); +is_flat(_, _N) -> + false. + printable_bin0(Bin, D, T, Enc) -> Len = case D >= 0 of true -> diff --git a/lib/stdlib/src/otp_internal.erl b/lib/stdlib/src/otp_internal.erl index f2b50c354a..b95cb8f525 100644 --- a/lib/stdlib/src/otp_internal.erl +++ b/lib/stdlib/src/otp_internal.erl @@ -44,8 +44,19 @@ obsolete(Module, Name, Arity) -> no end. -obsolete_1(net, _, _) -> - {deprecated, "module 'net' obsolete; use 'net_adm'"}; +obsolete_1(net, call, 4) -> + {deprecated, {rpc, call, 4}}; +obsolete_1(net, cast, 4) -> + {deprecated, {rpc, cast, 4}}; +obsolete_1(net, broadcast, 3) -> + {deprecated, {rpc, eval_everywhere, 3}}; +obsolete_1(net, ping, 1) -> + {deprecated, {net_adm, ping, 1}}; +obsolete_1(net, sleep, 1) -> + {deprecated, "Use 'receive after T -> ok end' instead"}; +obsolete_1(net, relay, 1) -> + {deprecated, {slave, relay, 1}}; + obsolete_1(erlang, now, 0) -> {deprecated, diff --git a/lib/stdlib/src/slave.erl b/lib/stdlib/src/slave.erl index 5e8c1a43ea..4791e3ebda 100644 --- a/lib/stdlib/src/slave.erl +++ b/lib/stdlib/src/slave.erl @@ -104,18 +104,17 @@ relay1(Pid) -> %% this to work is that the 'erl' program can be found in PATH. %% %% If the master and slave are on different hosts, start/N uses -%% the 'rsh' program to spawn an Erlang node on the other host. +%% the 'ssh' program to spawn an Erlang node on the other host. %% Alternative, if the master was started as %% 'erl -sname xxx -rsh my_rsh...', then 'my_rsh' will be used instead -%% of 'rsh' (this is useful for systems where the rsh program is named -%% 'remsh'). +%% of 'ssh' (this is useful for systems still using rsh or remsh). %% %% For this to work, the following conditions must be fulfilled: %% -%% 1. There must be an Rsh program on computer; if not an error +%% 1. There must be an ssh program on computer; if not an error %% is returned. %% -%% 2. The hosts must be configured to allowed 'rsh' access without +%% 2. The hosts must be configured to allow 'ssh' access without %% prompts for password. %% %% The slave node will have its filer and user server redirected @@ -286,7 +285,7 @@ register_unique_name(Number) -> %% Makes up the command to start the nodes. %% If the node should run on the local host, there is -%% no need to use rsh. +%% no need to use a remote shell. mk_cmd(Host, Name, Args, Waiter, Prog0) -> Prog = quote_progname(Prog0), @@ -342,9 +341,7 @@ do_quote_progname([Prog,Arg|Args]) -> lists:flatten(lists:map(fun(X) -> [" ",X] end, [Arg|Args])) end. -%% Give the user an opportunity to run another program, -%% than the "rsh". On HP-UX rsh is called remsh; thus HP users -%% must start erlang as erl -rsh remsh. +%% Give the user an opportunity to run another program than "ssh". %% %% Also checks that the given program exists. %% @@ -354,7 +351,7 @@ rsh() -> Rsh = case init:get_argument(rsh) of {ok, [[Prog]]} -> Prog; - _ -> "rsh" + _ -> "ssh" end, case os:find_executable(Rsh) of false -> {error, no_rsh}; diff --git a/lib/stdlib/src/stdlib.appup.src b/lib/stdlib/src/stdlib.appup.src index 2a324aef82..37ea97c353 100644 --- a/lib/stdlib/src/stdlib.appup.src +++ b/lib/stdlib/src/stdlib.appup.src @@ -38,7 +38,10 @@ {<<"^3\\.5\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]}, {<<"^3\\.5\\.1(?:\\.[0-9]+)*$">>,[restart_new_emulator]}, {<<"^3\\.6$">>,[restart_new_emulator]}, - {<<"^3\\.6\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]}], + {<<"^3\\.6\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]}, + {<<"^3\\.7$">>,[restart_new_emulator]}, + {<<"^3\\.7\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]}, + {<<"^3\\.7\\.1(?:\\.[0-9]+)*$">>,[restart_new_emulator]}], [{<<"^3\\.4$">>,[restart_new_emulator]}, {<<"^3\\.4\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]}, {<<"^3\\.4\\.1(?:\\.[0-9]+)*$">>,[restart_new_emulator]}, @@ -50,4 +53,7 @@ {<<"^3\\.5\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]}, {<<"^3\\.5\\.1(?:\\.[0-9]+)*$">>,[restart_new_emulator]}, {<<"^3\\.6$">>,[restart_new_emulator]}, - {<<"^3\\.6\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]}]}. + {<<"^3\\.6\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]}, + {<<"^3\\.7$">>,[restart_new_emulator]}, + {<<"^3\\.7\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]}, + {<<"^3\\.7\\.1(?:\\.[0-9]+)*$">>,[restart_new_emulator]}]}. diff --git a/lib/stdlib/src/sys.erl b/lib/stdlib/src/sys.erl index a04195c9ed..6ff9aa33b4 100644 --- a/lib/stdlib/src/sys.erl +++ b/lib/stdlib/src/sys.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2018. All Rights Reserved. +%% Copyright Ericsson AB 1996-2019. 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. @@ -37,7 +37,7 @@ %% Types %%----------------------------------------------------------------- --export_type([dbg_opt/0]). +-export_type([dbg_opt/0, dbg_fun/0, debug_option/0]). -type name() :: pid() | atom() | {'global', term()} @@ -75,6 +75,16 @@ Event :: system_event(), Extra :: term()) -> any()). +-type debug_option() :: + 'trace' + | 'log' + | {'log', N :: pos_integer()} + | 'statistics' + | {'log_to_file', FileName :: file:name()} + | {'install', + {Func :: dbg_fun(), FuncState :: term()} + | {FuncId :: term(), Func :: dbg_fun(), FuncState :: term()}}. + %%----------------------------------------------------------------- %% System messages %%----------------------------------------------------------------- @@ -734,19 +744,7 @@ nlog_get([_J|R]) -> %% Returns: [debug_opts()] %%----------------------------------------------------------------- --spec debug_options(Options) -> [dbg_opt()] when - Options :: [Opt], - Opt :: 'trace' - | 'log' - | {'log', pos_integer()} - | 'statistics' - | {'log_to_file', FileName} - | {'install', FuncSpec}, - FileName :: file:name(), - FuncSpec :: {Func, FuncState} | {FuncId, Func, FuncState}, - FuncId :: term(), - Func :: dbg_fun(), - FuncState :: term(). +-spec debug_options([Opt :: debug_option()]) -> [dbg_opt()]. debug_options(Options) -> debug_options(Options, []). |