aboutsummaryrefslogtreecommitdiffstats
path: root/lib/stdlib
diff options
context:
space:
mode:
Diffstat (limited to 'lib/stdlib')
-rw-r--r--lib/stdlib/doc/src/beam_lib.xml1
-rw-r--r--lib/stdlib/doc/src/filename.xml2
-rw-r--r--lib/stdlib/doc/src/lists.xml2
-rw-r--r--lib/stdlib/doc/src/sofs.xml2
-rw-r--r--lib/stdlib/doc/src/timer.xml25
-rw-r--r--lib/stdlib/src/beam_lib.erl1
-rw-r--r--lib/stdlib/src/escript.erl88
-rw-r--r--lib/stdlib/src/timer.erl13
-rw-r--r--lib/stdlib/test/ets_SUITE.erl21
-rw-r--r--lib/stdlib/test/timer_simple_SUITE.erl18
-rw-r--r--lib/stdlib/vsn.mk3
11 files changed, 112 insertions, 64 deletions
diff --git a/lib/stdlib/doc/src/beam_lib.xml b/lib/stdlib/doc/src/beam_lib.xml
index 27308e02f3..adc411e272 100644
--- a/lib/stdlib/doc/src/beam_lib.xml
+++ b/lib/stdlib/doc/src/beam_lib.xml
@@ -341,6 +341,7 @@ chunkref() = chunkname() | chunkid()</code>
<v>Beam1 = Beam2 = beam()</v>
<v>Reason = {modules_different, Module1, Module2}</v>
<v>&nbsp;&nbsp;| {chunks_different, ChunkId}</v>
+ <v>&nbsp;&nbsp;| different_chunks</v>
<v>&nbsp;&nbsp;| Reason1 -- see info/1</v>
<v>&nbsp;Module1 = Module2 = atom()</v>
<v>&nbsp;ChunkId = chunkid()</v>
diff --git a/lib/stdlib/doc/src/filename.xml b/lib/stdlib/doc/src/filename.xml
index 0cf82fa48b..fe6c6f898e 100644
--- a/lib/stdlib/doc/src/filename.xml
+++ b/lib/stdlib/doc/src/filename.xml
@@ -49,7 +49,7 @@
<title>DATA TYPES</title>
<code type="none">
name() = string() | atom() | DeepList
- DeepList = [char() | atom() | DeepList]</code>
+DeepList = [char() | atom() | DeepList]</code>
</section>
<funcs>
<func>
diff --git a/lib/stdlib/doc/src/lists.xml b/lib/stdlib/doc/src/lists.xml
index a273a2301f..b3ad7aaf46 100644
--- a/lib/stdlib/doc/src/lists.xml
+++ b/lib/stdlib/doc/src/lists.xml
@@ -48,7 +48,7 @@
<item><p>if x <c>F</c> y and y <c>F</c> x then x = y (<c>F</c>
is antisymmetric);</p>
</item>
- <item><p>if x <c>F</c> y and and y <c>F</c> z then x <c>F</c> z
+ <item><p>if x <c>F</c> y and y <c>F</c> z then x <c>F</c> z
(<c>F</c> is transitive);</p>
</item>
<item><p>x <c>F</c> y or y <c>F</c> x (<c>F</c> is total).</p>
diff --git a/lib/stdlib/doc/src/sofs.xml b/lib/stdlib/doc/src/sofs.xml
index 8c8ae51262..729df1e678 100644
--- a/lib/stdlib/doc/src/sofs.xml
+++ b/lib/stdlib/doc/src/sofs.xml
@@ -210,7 +210,7 @@
X[i] to Y[i] and S a subset of
X[1]&nbsp;&times;&nbsp;...&nbsp;&times;&nbsp;X[n].
The <marker id="multiple_relative_product"></marker><em>multiple
- relative product</em> of TR and and S is defined to be the
+ relative product</em> of TR and S is defined to be the
set {z&nbsp;: z&nbsp;= ((x[1],&nbsp;...,&nbsp;x[n]), (y[1],...,y[n]))
for some (x[1],&nbsp;...,&nbsp;x[n])&nbsp;in&nbsp;S and for some
(x[i],&nbsp;y[i]) in R[i],
diff --git a/lib/stdlib/doc/src/timer.xml b/lib/stdlib/doc/src/timer.xml
index 0b6807dd6c..1b34e71490 100644
--- a/lib/stdlib/doc/src/timer.xml
+++ b/lib/stdlib/doc/src/timer.xml
@@ -202,18 +202,33 @@
</func>
<func>
<name>tc(Module, Function, Arguments) -> {Time, Value}</name>
- <fsummary>Measure the real time it takes to evaluate <c>apply(Module, Function, Arguments)</c></fsummary>
+ <name>tc(Fun, Arguments) -> {Time, Value}</name>
+ <fsummary>Measure the real time it takes to evaluate <c>apply(Module,
+ Function, Arguments)</c> or <c>apply(Fun, Arguments)</c></fsummary>
<type>
<v>Module = Function = atom()</v>
+ <v>Fun = fun()</v>
<v>Arguments = [term()]</v>
<v>Time = integer() in microseconds</v>
<v>Value = term()</v>
</type>
<desc>
- <p>Evaluates <c>apply(Module, Function, Arguments)</c> and measures
- the elapsed real time. Returns <c>{Time, Value}</c>, where
- <c>Time</c> is the elapsed real time in <em>microseconds</em>,
- and <c>Value</c> is what is returned from the apply.</p>
+ <p></p>
+ <taglist>
+ <tag><c>tc/3</c></tag>
+ <item>
+ <p>Evaluates <c>apply(Module, Function, Arguments)</c> and measures
+ the elapsed real time as reported by <c>now/0</c>.
+ Returns <c>{Time, Value}</c>, where
+ <c>Time</c> is the elapsed real time in <em>microseconds</em>,
+ and <c>Value</c> is what is returned from the apply.</p>
+ </item>
+ <tag><c>tc/2</c></tag>
+ <item>
+ <p>Evaluates <c>apply(Fun, Arguments)</c>. Otherwise works
+ like <c>tc/3</c>.</p>
+ </item>
+ </taglist>
</desc>
</func>
<func>
diff --git a/lib/stdlib/src/beam_lib.erl b/lib/stdlib/src/beam_lib.erl
index 91ff2438c6..e612bf71e7 100644
--- a/lib/stdlib/src/beam_lib.erl
+++ b/lib/stdlib/src/beam_lib.erl
@@ -105,6 +105,7 @@
| info_rsn().
-type cmp_rsn() :: {'modules_different', module(), module()}
| {'chunks_different', chunkid()}
+ | 'different_chunks'
| info_rsn().
%%-------------------------------------------------------------------------
diff --git a/lib/stdlib/src/escript.erl b/lib/stdlib/src/escript.erl
index d26443f277..99e454f593 100644
--- a/lib/stdlib/src/escript.erl
+++ b/lib/stdlib/src/escript.erl
@@ -24,35 +24,41 @@
%% Internal API.
-export([start/0, start/1]).
--include_lib("kernel/include/file.hrl").
+%%-----------------------------------------------------------------------
-define(SHEBANG, "/usr/bin/env escript").
-define(COMMENT, "This is an -*- erlang -*- file").
--record(state, {file,
- module,
+%%-----------------------------------------------------------------------
+
+-type mode() :: 'compile' | 'debug' | 'interpret' | 'run'.
+-type source() :: 'archive' | 'beam' | 'text'.
+
+-record(state, {file :: file:filename(),
+ module :: module(),
forms_or_bin,
- source,
- n_errors,
- mode,
- exports_main,
- has_records}).
--record(sections, {type,
- shebang,
- comment,
- emu_args,
- body}).
--record(extract_options, {compile_source}).
+ source :: source(),
+ n_errors :: non_neg_integer(),
+ mode :: mode(),
+ exports_main :: boolean(),
+ has_records :: boolean()}).
-type shebang() :: string().
-type comment() :: string().
-type emu_args() :: string().
--type escript_filename() :: string().
--type filename() :: string().
+
+-record(sections, {type,
+ shebang :: shebang(),
+ comment :: comment(),
+ emu_args :: emu_args(),
+ body}).
+
+-record(extract_options, {compile_source}).
+
-type zip_file() ::
- filename()
- | {filename(), binary()}
- | {filename(), binary(), #file_info{}}.
+ file:filename()
+ | {file:filename(), binary()}
+ | {file:filename(), binary(), file:file_info()}.
-type zip_create_option() :: term().
-type section() ::
shebang
@@ -60,13 +66,15 @@
| comment
| {comment, comment()}
| {emu_args, emu_args()}
- | {source, filename() | binary()}
- | {beam, filename() | binary()}
- | {archive, filename() | binary()}
+ | {source, file:filename() | binary()}
+ | {beam, file:filename() | binary()}
+ | {archive, file:filename() | binary()}
| {archive, [zip_file()], [zip_create_option()]}.
+%%-----------------------------------------------------------------------
+
%% Create a complete escript file with both header and body
--spec create(escript_filename() | binary, [section()]) ->
+-spec create(file:filename() | binary, [section()]) ->
ok | {ok, binary()} | {error, term()}.
create(File, Options) when is_list(Options) ->
@@ -149,7 +157,9 @@ prepare(BadOptions, _) ->
-type section_name() :: shebang | comment | emu_args | body .
-type extract_option() :: compile_source | {section, [section_name()]}.
--spec extract(filename(), [extract_option()]) -> {ok, [section()]} | {error, term()}.
+-spec extract(file:filename(), [extract_option()]) ->
+ {ok, [section()]} | {error, term()}.
+
extract(File, Options) when is_list(File), is_list(Options) ->
try
EO = parse_extract_options(Options,
@@ -239,6 +249,7 @@ normalize_section(Name, Chars) ->
{Name, Chars}.
-spec script_name() -> string().
+
script_name() ->
[ScriptName|_] = init:get_plain_arguments(),
ScriptName.
@@ -248,10 +259,12 @@ script_name() ->
%%
-spec start() -> no_return().
+
start() ->
start([]).
-spec start([string()]) -> no_return().
+
start(EscriptOptions) ->
try
%% Commands run using -run or -s are run in a process
@@ -484,18 +497,12 @@ find_first_body_line(Fd, HeaderSz0, LineNo, KeepFirst, Sections) ->
classify_line(Line) ->
case Line of
- [$\#, $\! | _] ->
- shebang;
- [$P, $K | _] ->
- archive;
- [$F, $O, $R, $1 | _] ->
- beam;
- [$%, $%, $\! | _] ->
- emu_args;
- [$% | _] ->
- comment;
- _ ->
- undefined
+ "#!" ++ _ -> shebang;
+ "PK" ++ _ -> archive;
+ "FOR1" ++ _ -> beam;
+ "%%!" ++ _ -> emu_args;
+ "%" ++ _ -> comment;
+ _ -> undefined
end.
guess_type(Line) ->
@@ -531,7 +538,6 @@ parse_archive(S, File, HeaderSz) ->
end,
list_to_atom(lists:reverse(RevBase2))
end,
-
S#state{source = archive,
mode = run,
module = Mod,
@@ -587,8 +593,8 @@ parse_source(S, File, Fd, StartLine, HeaderSz, CheckOnly) ->
epp_parse_file2(Epp, S2, [ModForm, FileForm], OptModRes);
{error, _} ->
epp_parse_file2(Epp, S2, [FileForm], OptModRes);
- {eof,LastLine} ->
- S#state{forms_or_bin = [FileForm, {eof,LastLine}]}
+ {eof, _LastLine} = Eof ->
+ S#state{forms_or_bin = [FileForm, Eof]}
end,
ok = epp:close(Epp),
ok = file:close(Fd),
@@ -683,8 +689,8 @@ epp_parse_file2(Epp, S, Forms, Parsed) ->
io:format("~s:~w: ~s\n",
[S#state.file,Ln,Mod:format_error(Args)]),
epp_parse_file(Epp, S#state{n_errors = S#state.n_errors + 1}, [Form | Forms]);
- {eof,LastLine} ->
- S#state{forms_or_bin = lists:reverse([{eof, LastLine} | Forms])}
+ {eof, _LastLine} = Eof ->
+ S#state{forms_or_bin = lists:reverse([Eof | Forms])}
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/stdlib/src/timer.erl b/lib/stdlib/src/timer.erl
index 6ee837c3e6..24e14caa69 100644
--- a/lib/stdlib/src/timer.erl
+++ b/lib/stdlib/src/timer.erl
@@ -22,7 +22,7 @@
send_after/3, send_after/2,
exit_after/3, exit_after/2, kill_after/2, kill_after/1,
apply_interval/4, send_interval/3, send_interval/2,
- cancel/1, sleep/1, tc/3, now_diff/2,
+ cancel/1, sleep/1, tc/2, tc/3, now_diff/2,
seconds/1, minutes/1, hours/1, hms/3]).
-export([start_link/0, start/0,
@@ -98,6 +98,17 @@ sleep(T) ->
after T -> ok
end.
+
+%%
+%% Measure the execution time (in microseconds) for Fun(Args).
+%%
+-spec tc(function(), [_]) -> {time(), term()}.
+tc(F, A) ->
+ Before = erlang:now(),
+ Val = (catch apply(F, A)),
+ After = erlang:now(),
+ {now_diff(After, Before), Val}.
+
%%
%% Measure the execution time (in microseconds) for an MFA.
%%
diff --git a/lib/stdlib/test/ets_SUITE.erl b/lib/stdlib/test/ets_SUITE.erl
index 1f68c6b8c4..5d7e558601 100644
--- a/lib/stdlib/test/ets_SUITE.erl
+++ b/lib/stdlib/test/ets_SUITE.erl
@@ -63,7 +63,8 @@
meta_lookup_unnamed_read/1, meta_lookup_unnamed_write/1,
meta_lookup_named_read/1, meta_lookup_named_write/1,
meta_newdel_unnamed/1, meta_newdel_named/1]).
--export([smp_insert/1, smp_fixed_delete/1, smp_unfix_fix/1, smp_select_delete/1, otp_8166/1]).
+-export([smp_insert/1, smp_fixed_delete/1, smp_unfix_fix/1, smp_select_delete/1,
+ otp_8166/1, otp_8732/1]).
-export([exit_large_table_owner/1,
exit_many_large_table_owner/1,
exit_many_tables_owner/1,
@@ -130,7 +131,7 @@ all(suite) ->
t_select_delete, t_ets_dets, memory,
t_bucket_disappears,
select_fail,t_insert_new, t_repair_continuation, otp_5340, otp_6338,
- otp_6842_select_1000, otp_7665,
+ otp_6842_select_1000, otp_7665, otp_8732,
meta_wb,
grow_shrink, grow_pseudo_deleted, shrink_pseudo_deleted,
meta_smp,
@@ -392,7 +393,7 @@ memory(Config) when is_list(Config) ->
?line erts_debug:set_internal_state(available_internal_state, true),
?line ok = chk_normal_tab_struct_size(),
?line L = [T1,T2,T3,T4] = fill_sets_int(1000),
- ?line XRes1 = adjust_xmem(L, {16862,16072,16072,16078}),
+ ?line XRes1 = adjust_xmem(L, {14862,14072,14072,14078}),
?line Res1 = {?S(T1),?S(T2),?S(T3),?S(T4)},
?line lists:foreach(fun(T) ->
Before = ets:info(T,size),
@@ -403,7 +404,7 @@ memory(Config) when is_list(Config) ->
[Key, ets:info(T,type), Before, ets:info(T,size), Objs])
end,
L),
- ?line XRes2 = adjust_xmem(L, {16849,16060,16048,16054}),
+ ?line XRes2 = adjust_xmem(L, {14851,14062,14052,14058}),
?line Res2 = {?S(T1),?S(T2),?S(T3),?S(T4)},
?line lists:foreach(fun(T) ->
Before = ets:info(T,size),
@@ -414,7 +415,7 @@ memory(Config) when is_list(Config) ->
[Key, ets:info(T,type), Before, ets:info(T,size), Objs])
end,
L),
- ?line XRes3 = adjust_xmem(L, {16836,16048,16024,16030}),
+ ?line XRes3 = adjust_xmem(L, {14840,14052,14032,14038}),
?line Res3 = {?S(T1),?S(T2),?S(T3),?S(T4)},
?line lists:foreach(fun(T) ->
?line ets:delete_all_objects(T)
@@ -5049,8 +5050,14 @@ verify_table_load(T) ->
end.
-
-
+otp_8732(doc) -> ["ets:select on a tree with NIL key object"];
+otp_8732(Config) when is_list(Config) ->
+ Tab = ets:new(noname,[ordered_set]),
+ filltabstr(Tab,999),
+ ets:insert(Tab,{[],"nasty NIL object"}),
+ ?line [] = ets:match(Tab,{'_',nomatch}), %% Will hang if bug not fixed
+ ok.
+
smp_select_delete(suite) -> [];
smp_select_delete(doc) ->
diff --git a/lib/stdlib/test/timer_simple_SUITE.erl b/lib/stdlib/test/timer_simple_SUITE.erl
index 021a22c61b..6aa2b7b945 100644
--- a/lib/stdlib/test/timer_simple_SUITE.erl
+++ b/lib/stdlib/test/timer_simple_SUITE.erl
@@ -224,11 +224,19 @@ cancel2(Config) when is_list(Config) ->
tc(doc) -> "Test sleep/1 and tc/3.";
tc(suite) -> [];
tc(Config) when is_list(Config) ->
- % This should both sleep and tc
- ?line {Res, ok} = timer:tc(timer, sleep, [500]),
- ?line ok = if
- Res < 500*1000 -> {too_early, Res}; % Too early
- Res > 800*1000 -> {too_late, Res}; % Too much time
+ % This should both sleep and tc/3
+ ?line {Res1, ok} = timer:tc(timer, sleep, [500]),
+ ?line ok = if
+ Res1 < 500*1000 -> {too_early, Res1}; % Too early
+ Res1 > 800*1000 -> {too_late, Res1}; % Too much time
+ true -> ok
+ end,
+
+ % This should both sleep and tc/2
+ ?line {Res2, ok} = timer:tc(fun(T) -> timer:sleep(T) end, [500]),
+ ?line ok = if
+ Res2 < 500*1000 -> {too_early, Res2}; % Too early
+ Res2 > 800*1000 -> {too_late, Res2}; % Too much time
true -> ok
end,
diff --git a/lib/stdlib/vsn.mk b/lib/stdlib/vsn.mk
index f081bd60e2..02ea6d9d68 100644
--- a/lib/stdlib/vsn.mk
+++ b/lib/stdlib/vsn.mk
@@ -17,5 +17,4 @@
# %CopyrightEnd%
#
-STDLIB_VSN = 1.17
-
+STDLIB_VSN = 1.17.1