aboutsummaryrefslogtreecommitdiffstats
path: root/lib/stdlib
diff options
context:
space:
mode:
Diffstat (limited to 'lib/stdlib')
-rw-r--r--lib/stdlib/doc/src/array.xml4
-rw-r--r--lib/stdlib/doc/src/assert_hrl.xml11
-rw-r--r--lib/stdlib/doc/src/beam_lib.xml18
-rw-r--r--lib/stdlib/doc/src/binary.xml4
-rw-r--r--lib/stdlib/doc/src/c.xml2
-rw-r--r--lib/stdlib/doc/src/calendar.xml4
-rw-r--r--lib/stdlib/doc/src/dets.xml56
-rw-r--r--lib/stdlib/doc/src/digraph.xml6
-rw-r--r--lib/stdlib/doc/src/digraph_utils.xml5
-rw-r--r--lib/stdlib/doc/src/epp.xml2
-rw-r--r--lib/stdlib/doc/src/erl_anno.xml34
-rw-r--r--lib/stdlib/doc/src/erl_parse.xml2
-rw-r--r--lib/stdlib/doc/src/erl_pp.xml4
-rw-r--r--lib/stdlib/doc/src/erl_scan.xml187
-rw-r--r--lib/stdlib/doc/src/erl_tar.xml3
-rw-r--r--lib/stdlib/doc/src/ets.xml15
-rw-r--r--lib/stdlib/doc/src/file_sorter.xml52
-rw-r--r--lib/stdlib/doc/src/gen_event.xml4
-rw-r--r--lib/stdlib/doc/src/gen_fsm.xml2
-rw-r--r--lib/stdlib/doc/src/gen_server.xml2
-rw-r--r--lib/stdlib/doc/src/io.xml18
-rw-r--r--lib/stdlib/doc/src/lists.xml6
-rw-r--r--lib/stdlib/doc/src/math.xml2
-rw-r--r--lib/stdlib/doc/src/notes.xml114
-rw-r--r--lib/stdlib/doc/src/rand.xml2
-rw-r--r--lib/stdlib/doc/src/random.xml16
-rw-r--r--lib/stdlib/doc/src/re.xml16
-rw-r--r--lib/stdlib/doc/src/sofs.xml5
-rw-r--r--lib/stdlib/doc/src/supervisor.xml2
-rw-r--r--lib/stdlib/doc/src/sys.xml4
-rw-r--r--lib/stdlib/doc/src/timer.xml8
-rw-r--r--lib/stdlib/doc/src/unicode.xml2
-rw-r--r--lib/stdlib/doc/src/zip.xml2
-rw-r--r--lib/stdlib/include/erl_bits.hrl10
-rw-r--r--lib/stdlib/src/beam_lib.erl19
-rw-r--r--lib/stdlib/src/binary.erl77
-rw-r--r--lib/stdlib/src/edlin.erl4
-rw-r--r--lib/stdlib/src/epp.erl329
-rw-r--r--lib/stdlib/src/erl_anno.erl96
-rw-r--r--lib/stdlib/src/erl_eval.erl2
-rw-r--r--lib/stdlib/src/erl_lint.erl54
-rw-r--r--lib/stdlib/src/erl_parse.yrl63
-rw-r--r--lib/stdlib/src/erl_pp.erl21
-rw-r--r--lib/stdlib/src/erl_scan.erl267
-rw-r--r--lib/stdlib/src/escript.erl8
-rw-r--r--lib/stdlib/src/io.erl43
-rw-r--r--lib/stdlib/src/otp_internal.erl63
-rw-r--r--lib/stdlib/src/rand.erl2
-rw-r--r--lib/stdlib/src/random.erl1
-rw-r--r--lib/stdlib/src/shell.erl15
-rw-r--r--lib/stdlib/src/slave.erl23
-rw-r--r--lib/stdlib/src/stdlib.appup.src8
-rw-r--r--lib/stdlib/src/supervisor.erl76
-rw-r--r--lib/stdlib/test/base64_SUITE.erl2
-rw-r--r--lib/stdlib/test/binary_module_SUITE.erl40
-rw-r--r--lib/stdlib/test/dict_SUITE.erl16
-rw-r--r--lib/stdlib/test/epp_SUITE.erl79
-rw-r--r--lib/stdlib/test/erl_anno_SUITE.erl72
-rw-r--r--lib/stdlib/test/erl_eval_SUITE.erl10
-rw-r--r--lib/stdlib/test/erl_lint_SUITE.erl104
-rw-r--r--lib/stdlib/test/erl_pp_SUITE.erl20
-rw-r--r--lib/stdlib/test/erl_scan_SUITE.erl279
-rw-r--r--lib/stdlib/test/ets_SUITE.erl98
-rw-r--r--lib/stdlib/test/ets_tough_SUITE.erl10
-rw-r--r--lib/stdlib/test/filelib_SUITE.erl2
-rw-r--r--lib/stdlib/test/filename_SUITE.erl35
-rw-r--r--lib/stdlib/test/lists_SUITE.erl22
-rw-r--r--lib/stdlib/test/queue_SUITE.erl10
-rw-r--r--lib/stdlib/test/rand_SUITE.erl3
-rw-r--r--lib/stdlib/test/random_iolist.erl16
-rw-r--r--lib/stdlib/test/random_unicode_list.erl18
-rw-r--r--lib/stdlib/test/run_pcre_tests.erl10
-rw-r--r--lib/stdlib/test/select_SUITE.erl21
-rw-r--r--lib/stdlib/test/sets_SUITE.erl22
-rw-r--r--lib/stdlib/test/timer_SUITE.erl24
-rw-r--r--lib/stdlib/vsn.mk2
76 files changed, 1021 insertions, 1689 deletions
diff --git a/lib/stdlib/doc/src/array.xml b/lib/stdlib/doc/src/array.xml
index 28b4435938..0f33e2621c 100644
--- a/lib/stdlib/doc/src/array.xml
+++ b/lib/stdlib/doc/src/array.xml
@@ -164,7 +164,7 @@ the default value cannot be confused with the values of set entries.</p>
</fsummary>
<desc><marker id="from_list-1"/>
-<p>Equivalent to <seealso marker="#from_list-2">from_list(<anno>List</anno>, undefined)</seealso>.</p>
+<p>Equivalent to <seealso marker="#from_list-2">from_list(<c><anno>List</anno></c>, undefined)</seealso>.</p>
</desc></func>
<func>
<name name="from_list" arity="2"/>
@@ -184,7 +184,7 @@ the default value cannot be confused with the values of set entries.</p>
</fsummary>
<desc><marker id="from_orddict-1"/>
-<p>Equivalent to <seealso marker="#from_orddict-2">from_orddict(<anno>Orddict</anno>, undefined)</seealso>.</p>
+<p>Equivalent to <seealso marker="#from_orddict-2">from_orddict(<c><anno>Orddict</anno></c>, undefined)</seealso>.</p>
</desc></func>
<func>
<name name="from_orddict" arity="2"/>
diff --git a/lib/stdlib/doc/src/assert_hrl.xml b/lib/stdlib/doc/src/assert_hrl.xml
index b85be514d8..ef4f928e57 100644
--- a/lib/stdlib/doc/src/assert_hrl.xml
+++ b/lib/stdlib/doc/src/assert_hrl.xml
@@ -77,9 +77,6 @@ erlc -DNOASSERT=true *.erl</code>
</description>
<section>
- </section>
-
- <section>
<title>Macros</title>
<taglist>
<tag><c>assert(BoolExpr)</c></tag>
@@ -94,12 +91,12 @@ erlc -DNOASSERT=true *.erl</code>
<tag><c>assertMatch(GuardedPattern, Expr)</c></tag>
<item><p>Tests that <c>Expr</c> completes normally yielding a value
- that matches <c>GuardedPattern</c>. For example:
+ that matches <c>GuardedPattern</c>. For example:</p>
<code type="none">
- ?assertMatch({bork, _}, f())</code></p>
- <p>Note that a guard <c>when ...</c> can be included:
+ ?assertMatch({bork, _}, f())</code>
+ <p>Note that a guard <c>when ...</c> can be included:</p>
<code type="none">
- ?assertMatch({bork, X} when X > 0, f())</code></p>
+ ?assertMatch({bork, X} when X > 0, f())</code>
</item>
<tag><c>assertNotMatch(GuardedPattern, Expr)</c></tag>
diff --git a/lib/stdlib/doc/src/beam_lib.xml b/lib/stdlib/doc/src/beam_lib.xml
index c556180b8b..7c89c8b43e 100644
--- a/lib/stdlib/doc/src/beam_lib.xml
+++ b/lib/stdlib/doc/src/beam_lib.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2000</year><year>2013</year>
+ <year>2000</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -71,6 +71,7 @@
using <seealso marker="#strip/1">strip/1</seealso>,
<seealso marker="#strip_files/1">strip_files/1</seealso> and/or
<seealso marker="#strip_release/1">strip_release/1</seealso>.</p>
+ </section>
<section>
<title>Reconstructing source code</title>
<p>Here is an example of how to reconstruct source code from
@@ -152,7 +153,6 @@
keys.</p>
</note>
</section>
- </section>
<datatypes>
<datatype>
@@ -224,6 +224,13 @@
<funcs>
<func>
+ <name name="all_chunks" arity="1"/>
+ <fsummary>Read all chunks from a BEAM file or binary</fsummary>
+ <desc>
+ <p>Reads chunk data for all chunks.</p>
+ </desc>
+ </func>
+ <func>
<name name="chunks" arity="2"/>
<fsummary>Read selected chunks from a BEAM file or binary</fsummary>
<desc>
@@ -251,6 +258,13 @@
</desc>
</func>
<func>
+ <name name="build_module" arity="1"/>
+ <fsummary>Creates a BEAM module from a list of chunks</fsummary>
+ <desc>
+ <p>Builds a BEAM module (as a binary) from a list of chunks.</p>
+ </desc>
+ </func>
+ <func>
<name name="version" arity="1"/>
<fsummary>Read the BEAM file's module version</fsummary>
<desc>
diff --git a/lib/stdlib/doc/src/binary.xml b/lib/stdlib/doc/src/binary.xml
index 063f3048e0..2682198fe5 100644
--- a/lib/stdlib/doc/src/binary.xml
+++ b/lib/stdlib/doc/src/binary.xml
@@ -299,8 +299,8 @@
</func>
<func>
<name name="match" arity="3"/>
- <type name="part"/>
<fsummary>Searches for the first match of a pattern in a binary</fsummary>
+ <type name="part"/>
<desc>
<p>Searches for the first occurrence of <c><anno>Pattern</anno></c> in <c><anno>Subject</anno></c> and
@@ -353,8 +353,8 @@
</func>
<func>
<name name="matches" arity="3"/>
- <type name="part"/>
<fsummary>Searches for all matches of a pattern in a binary</fsummary>
+ <type name="part"/>
<desc>
<p>Works like <c>match/2</c>, but the <c><anno>Subject</anno></c> is searched until
diff --git a/lib/stdlib/doc/src/c.xml b/lib/stdlib/doc/src/c.xml
index a0f18bd899..e5238fa7db 100644
--- a/lib/stdlib/doc/src/c.xml
+++ b/lib/stdlib/doc/src/c.xml
@@ -121,12 +121,12 @@ compile:file(<anno>File</anno>, <anno>Options</anno> ++ [report_errors, report_w
</func>
<func>
<name>lc(Files) -> ok</name>
+ <fsummary>Compile a list of files</fsummary>
<type>
<v>Files = [File]</v>
<v>File = <seealso marker="file#type-filename">file:filename()
</seealso></v>
</type>
- <fsummary>Compile a list of files</fsummary>
<desc>
<p>Compiles a list of files by calling <c>compile:file(File, [report_errors, report_warnings])</c> for each <c>File</c>
in <c>Files</c>.</p>
diff --git a/lib/stdlib/doc/src/calendar.xml b/lib/stdlib/doc/src/calendar.xml
index a8d933dc83..853184dc0f 100644
--- a/lib/stdlib/doc/src/calendar.xml
+++ b/lib/stdlib/doc/src/calendar.xml
@@ -130,11 +130,11 @@
<func>
<name name="date_to_gregorian_days" arity="1"/>
<name name="date_to_gregorian_days" arity="3"/>
+ <fsummary>Compute the number of days from year 0 up to the given date</fsummary>
<type variable="Date" name_i="1"/>
<type variable="Year"/>
<type variable="Month"/>
<type variable="Day"/>
- <fsummary>Compute the number of days from year 0 up to the given date</fsummary>
<desc>
<p>This function computes the number of gregorian days starting
with year 0 and ending at the given date.</p>
@@ -347,11 +347,11 @@
<func>
<name name="valid_date" arity="1"/>
<name name="valid_date" arity="3"/>
+ <fsummary>Check if a date is valid</fsummary>
<type variable="Date" name_i="1"/>
<type variable="Year"/>
<type variable="Month"/>
<type variable="Day"/>
- <fsummary>Check if a date is valid</fsummary>
<desc>
<p>This function checks if a date is a valid.</p>
</desc>
diff --git a/lib/stdlib/doc/src/dets.xml b/lib/stdlib/doc/src/dets.xml
index 14237b6f90..a0d3f95b6a 100644
--- a/lib/stdlib/doc/src/dets.xml
+++ b/lib/stdlib/doc/src/dets.xml
@@ -316,20 +316,20 @@
bytes.</p>
</item>
<item>
- <p><c>{filename, <seealso marker="file#type-name">file:name()</seealso>}</c>,
+ <p><c>{filename, </c><seealso marker="file#type-name">file:name()</seealso><c>}</c>,
the name of the file where objects are stored.</p>
</item>
<item>
- <p><c>{keypos, <seealso marker="#type-keypos">keypos()</seealso>}
- </c>, the position of the key.</p>
+ <p><c>{keypos, </c><seealso marker="#type-keypos">keypos()</seealso>
+ <c>}</c>, the position of the key.</p>
</item>
<item>
<p><c>{size, integer() >= 0}</c>, the number of objects stored
in the table.</p>
</item>
<item>
- <p><c>{type, <seealso marker="#type-type">type()</seealso>}</c>,
- the type of the table.</p>
+ <p><c>{type, </c><seealso marker="#type-type">type()</seealso>
+ <c>}</c>, the type of the table.</p>
</item>
</list>
</desc>
@@ -345,12 +345,12 @@
allowed:</p>
<list type="bulleted">
<item>
- <p><c>{access, <seealso marker="#type-access">access()</seealso>}
- </c>, the access mode.</p>
+ <p><c>{access, </c><seealso marker="#type-access">access()</seealso>
+ <c>}</c>, the access mode.</p>
</item>
<item>
- <p><c>{auto_save, <seealso marker="#type-auto_save">
- auto_save()</seealso>}</c>, the auto save interval.</p>
+ <p><c>{auto_save, </c><seealso marker="#type-auto_save">
+ auto_save()</seealso><c>}</c>, the auto save interval.</p>
</item>
<item>
<p><c>{bchunk_format, binary()}</c>, an opaque binary
@@ -730,16 +730,16 @@ ok
tuples where the following values are allowed:</p>
<list type="bulleted">
<item>
- <p><c>{access, <seealso marker="#type-access">
- access()</seealso>}</c>. It is possible to open
+ <p><c>{access, </c><seealso marker="#type-access">
+ access()</seealso><c>}</c>. It is possible to open
existing tables in read-only mode. A table which is opened
in read-only mode is not subjected to the automatic file
reparation algorithm if it is later opened after a crash.
The default value is <c>read_write</c>.</p>
</item>
<item>
- <p><c>{auto_save, <seealso marker="#type-auto_save">
- auto_save()</seealso>}</c>, the auto save
+ <p><c>{auto_save, </c><seealso marker="#type-auto_save">
+ auto_save()</seealso><c>}</c>, the auto save
interval. If the interval is an integer <c>Time</c>, the
table is flushed to disk whenever it is not accessed for
<c>Time</c> milliseconds. A table that has been flushed
@@ -749,18 +749,18 @@ ok
is 180000 (3 minutes).</p>
</item>
<item>
- <p><c>{estimated_no_objects, <seealso marker="#type-no_slots">
- no_slots()</seealso>}</c>. Equivalent to the
+ <p><c>{estimated_no_objects, </c><seealso marker="#type-no_slots">
+ no_slots()</seealso><c>}</c>. Equivalent to the
<c>min_no_slots</c> option.</p>
</item>
<item>
- <p><c>{file, <seealso marker="file#type-name">
- file:name()</seealso>}</c>, the name of the file to be
+ <p><c>{file, </c><seealso marker="file#type-name">
+ file:name()</seealso><c>}</c>, the name of the file to be
opened. The default value is the name of the table.</p>
</item>
<item>
- <p><c>{max_no_slots, <seealso marker="#type-no_slots">
- no_slots()</seealso>}</c>, the maximum number
+ <p><c>{max_no_slots, </c><seealso marker="#type-no_slots">
+ no_slots()</seealso><c>}</c>, the maximum number
of slots that will be used. The default value as well as
the maximal value is 32 M. Note that a higher value may
increase the fragmentation of the table, and conversely,
@@ -769,16 +769,16 @@ ok
9 tables.</p>
</item>
<item>
- <p><c>{min_no_slots, <seealso marker="#type-no_slots">
- no_slots()</seealso>}</c>. Application
+ <p><c>{min_no_slots, </c><seealso marker="#type-no_slots">
+ no_slots()</seealso><c>}</c>. Application
performance can be enhanced with this flag by specifying,
when the table is created, the estimated number of
different keys that will be stored in the table. The
default value as well as the minimum value is 256.</p>
</item>
<item>
- <p><c>{keypos, <seealso marker="#type-keypos">
- keypos()</seealso>}</c>, the position of the
+ <p><c>{keypos, </c><seealso marker="#type-keypos">
+ keypos()</seealso><c>}</c>, the position of the
element of each object to be used as key. The default
value is 1. The ability to explicitly state the key
position is most convenient when we want to store Erlang
@@ -815,12 +815,12 @@ ok
already open.</p>
</item>
<item>
- <p><c>{type, <seealso marker="#type-type">type()</seealso>}</c>,
+ <p><c>{type, </c><seealso marker="#type-type">type()</seealso><c>}</c>,
the type of the table. The default value is <c>set</c>.</p>
</item>
<item>
- <p><c>{version, <seealso marker="#type-version">
- version()</seealso>}</c>, the version of the format
+ <p><c>{version, </c><seealso marker="#type-version">
+ version()</seealso><c>}</c>, the version of the format
used for the table. The default value is <c>9</c>. Tables
on the format used before OTP R8 can be created by giving
the value <c>8</c>. A version 8 table can be converted to
@@ -1036,8 +1036,8 @@ ok
specification that matches all objects.</p>
</item>
<item>
- <p><c>{select, <seealso marker="#type-match_spec">
- match_spec()}</seealso></c>. As for <c>select</c>
+ <p><c>{select, </c><seealso marker="#type-match_spec">
+ match_spec()</seealso><c>}</c>. As for <c>select</c>
the table is traversed by calling <c>dets:select/3</c>
and <c>dets:select/1</c>. The difference is that the
match specification is explicitly given. This is how to
diff --git a/lib/stdlib/doc/src/digraph.xml b/lib/stdlib/doc/src/digraph.xml
index 49dc68e103..291be6c08b 100644
--- a/lib/stdlib/doc/src/digraph.xml
+++ b/lib/stdlib/doc/src/digraph.xml
@@ -103,13 +103,15 @@
<desc><p>A digraph as returned by <c>new/0,1</c>.</p></desc>
</datatype>
<datatype>
- <name><marker id="type-edge">edge()</marker></name>
+ <name>edge()</name>
+ <desc><p><marker id="type-edge"/></p></desc>
</datatype>
<datatype>
<name name="label"/>
</datatype>
<datatype>
- <name><marker id="type-vertex">vertex()</marker></name>
+ <name>vertex()</name>
+ <desc><p><marker id="type-vertex"/></p></desc>
</datatype>
</datatypes>
<funcs>
diff --git a/lib/stdlib/doc/src/digraph_utils.xml b/lib/stdlib/doc/src/digraph_utils.xml
index 6a4db2e963..639069543c 100644
--- a/lib/stdlib/doc/src/digraph_utils.xml
+++ b/lib/stdlib/doc/src/digraph_utils.xml
@@ -122,8 +122,9 @@
<datatypes>
<datatype>
- <name><marker id="type-digraph">digraph()</marker></name>
- <desc><p>A digraph as returned by <c>digraph:new/0,1</c>.</p></desc>
+ <name>digraph()</name>
+ <desc><p><marker id="type-digraph"/>
+ A digraph as returned by <c>digraph:new/0,1</c>.</p></desc>
</datatype>
</datatypes>
<funcs>
diff --git a/lib/stdlib/doc/src/epp.xml b/lib/stdlib/doc/src/epp.xml
index fe2944bbf7..8c901f57ec 100644
--- a/lib/stdlib/doc/src/epp.xml
+++ b/lib/stdlib/doc/src/epp.xml
@@ -39,7 +39,7 @@
by <c>compile</c> to preprocess macros and include files before
the actual parsing takes place.</p>
<p>The Erlang source file <marker
- id="encoding"><em>encoding</em></marker> is selected by a
+ id="encoding"/><em>encoding</em> is selected by a
comment in one of the first two lines of the source file. The
first string that matches the regular expression
<c>coding\s*[:=]\s*([-a-zA-Z0-9])+</c> selects the encoding. If
diff --git a/lib/stdlib/doc/src/erl_anno.xml b/lib/stdlib/doc/src/erl_anno.xml
index be0ffe6f4d..ddc8b8c765 100644
--- a/lib/stdlib/doc/src/erl_anno.xml
+++ b/lib/stdlib/doc/src/erl_anno.xml
@@ -44,7 +44,7 @@
<p>This module implements an abstract type that is used by the
Erlang Compiler and its helper modules for holding data such as
column, line number, and text. The data type is a collection of
- <marker id="annotations"><em>annotations</em></marker> as
+ <marker id="annotations"/><em>annotations</em> as
described in the following.</p>
<p>The Erlang Token Scanner returns tokens with a subset of
the following annotations, depending on the options:</p>
@@ -102,8 +102,8 @@
<datatypes>
<datatype>
- <name><marker id="type-anno">anno()</marker></name>
- <desc><p>A collection of annotations.</p>
+ <name>anno()</name>
+ <desc><p><marker id="type-anno"/>A collection of annotations.</p>
</desc>
</datatype>
<datatype>
@@ -133,8 +133,8 @@
<funcs>
<func>
<name name="column" arity="1"/>
- <type name="column"></type>
<fsummary>Return the column</fsummary>
+ <type name="column"></type>
<desc>
<p>Returns the column of the annotations <anno>Anno</anno>.
</p>
@@ -142,8 +142,8 @@
</func>
<func>
<name name="end_location" arity="1"/>
- <type name="location"></type>
<fsummary>Return the end location of the text</fsummary>
+ <type name="location"></type>
<desc>
<p>Returns the end location of the text of the
annotations <anno>Anno</anno>. If there is no text,
@@ -153,8 +153,8 @@
</func>
<func>
<name name="file" arity="1"/>
- <type name="filename"></type>
<fsummary>Return the filename</fsummary>
+ <type name="filename"></type>
<desc>
<p>Returns the filename of the annotations <anno>Anno</anno>.
If there is no filename, <c>undefined</c> is returned.
@@ -180,8 +180,8 @@
</func>
<func>
<name name="generated" arity="1"/>
- <type name="generated"></type>
<fsummary>Return the generated Boolean</fsummary>
+ <type name="generated"></type>
<desc>
<p>Returns <c>true</c> if the annotations <anno>Anno</anno>
has been marked as generated. The default is to return
@@ -199,8 +199,8 @@
</func>
<func>
<name name="line" arity="1"/>
- <type name="line"></type>
<fsummary>Return the line</fsummary>
+ <type name="line"></type>
<desc>
<p>Returns the line of the annotations <anno>Anno</anno>.
</p>
@@ -208,8 +208,8 @@
</func>
<func>
<name name="location" arity="1"/>
- <type name="location"></type>
<fsummary>Return the location</fsummary>
+ <type name="location"></type>
<desc>
<p>Returns the location of the annotations <anno>Anno</anno>.
</p>
@@ -217,16 +217,16 @@
</func>
<func>
<name name="new" arity="1"/>
- <type name="location"></type>
<fsummary>Create a new collection of annotations</fsummary>
+ <type name="location"></type>
<desc>
<p>Creates a new collection of annotations given a location.</p>
</desc>
</func>
<func>
<name name="set_file" arity="2"/>
- <type name="filename"></type>
<fsummary>Modify the filename</fsummary>
+ <type name="filename"></type>
<desc>
<p>Modifies the filename of the annotations <anno>Anno</anno>.
</p>
@@ -234,8 +234,8 @@
</func>
<func>
<name name="set_generated" arity="2"/>
- <type name="generated"></type>
<fsummary>Modify the generated marker</fsummary>
+ <type name="generated"></type>
<desc>
<p>Modifies the generated marker of the annotations
<anno>Anno</anno>.
@@ -244,8 +244,8 @@
</func>
<func>
<name name="set_line" arity="2"/>
- <type name="line"></type>
<fsummary>Modify the line</fsummary>
+ <type name="line"></type>
<desc>
<p>Modifies the line of the annotations <anno>Anno</anno>.
</p>
@@ -253,8 +253,8 @@
</func>
<func>
<name name="set_location" arity="2"/>
- <type name="location"></type>
<fsummary>Modify the location</fsummary>
+ <type name="location"></type>
<desc>
<p>Modifies the location of the annotations <anno>Anno</anno>.
</p>
@@ -262,8 +262,8 @@
</func>
<func>
<name name="set_record" arity="2"/>
- <type name="record"></type>
<fsummary>Modify the record marker</fsummary>
+ <type name="record"></type>
<desc>
<p>Modifies the record marker of the annotations <anno>Anno</anno>.
</p>
@@ -271,8 +271,8 @@
</func>
<func>
<name name="set_text" arity="2"/>
- <type name="text"></type>
<fsummary>Modify the text</fsummary>
+ <type name="text"></type>
<desc>
<p>Modifies the text of the annotations <anno>Anno</anno>.
</p>
@@ -280,8 +280,8 @@
</func>
<func>
<name name="text" arity="1"/>
- <type name="text"></type>
<fsummary>Return the text</fsummary>
+ <type name="text"></type>
<desc>
<p>Returns the text of the annotations <anno>Anno</anno>.
If there is no text, <c>undefined</c> is returned.
diff --git a/lib/stdlib/doc/src/erl_parse.xml b/lib/stdlib/doc/src/erl_parse.xml
index fdd776b7f1..0938b5dec3 100644
--- a/lib/stdlib/doc/src/erl_parse.xml
+++ b/lib/stdlib/doc/src/erl_parse.xml
@@ -174,8 +174,8 @@
</func>
<func>
<name name="abstract" arity="2"/>
- <type name="encoding_func"/>
<fsummary>Convert an Erlang term into an abstract form</fsummary>
+ <type name="encoding_func"/>
<desc>
<p>Converts the Erlang data structure <c><anno>Data</anno></c> into an
abstract form of type <c><anno>AbsTerm</anno></c>.</p>
diff --git a/lib/stdlib/doc/src/erl_pp.xml b/lib/stdlib/doc/src/erl_pp.xml
index c9d9e2723d..4b8a571c81 100644
--- a/lib/stdlib/doc/src/erl_pp.xml
+++ b/lib/stdlib/doc/src/erl_pp.xml
@@ -48,8 +48,8 @@
<datatype>
<name name="hook_function"/>
<desc>
- <p>The optional argument <marker id="hook_function">
- <c>HookFunction</c></marker>, shown in the functions described below,
+ <p>The optional argument <marker id="hook_function"/>
+ <c>HookFunction</c>, shown in the functions described below,
defines a function which is called when an unknown form occurs where there
should be a valid expression.</p>
diff --git a/lib/stdlib/doc/src/erl_scan.xml b/lib/stdlib/doc/src/erl_scan.xml
index 18e988e286..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>
@@ -181,10 +152,10 @@
<func>
<name name="tokens" arity="3"/>
<name name="tokens" arity="4"/>
+ <fsummary>Re-entrant scanner</fsummary>
<type name="char_spec"/>
<type name="return_cont"/>
<type_desc name="return_cont">An opaque continuation</type_desc>
- <fsummary>Re-entrant scanner</fsummary>
<desc>
<p>This is the re-entrant scanner which scans characters until
a <em>dot</em> ('.' followed by a white space) or
@@ -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"/>
- <type name="token_item"/>
- <type name="attribute_item"/>
- <fsummary>Return information about a token</fsummary>
- <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, <seealso marker="#type-category">
- category()</seealso>}</c></tag>
- <item><p>The category of the token.</p>
- </item>
- <tag><c>{column, <seealso marker="#type-column">
- column()</seealso>}</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, <seealso marker="#type-line">
- line()</seealso>}</c></tag>
- <item><p>The line where the token begins.</p>
- </item>
- <tag><c>{location, <seealso marker="#type-location">
- location()</seealso>}</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, <seealso marker="#type-symbol">
- symbol()</seealso>}</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, <seealso marker="#type-column">
- column()</seealso>}</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, <seealso marker="#type-line">
- line()</seealso>}</c></tag>
- <item><p>The line where the token begins.</p>
- </item>
- <tag><c>{location, <seealso marker="#type-location">
- location()</seealso>}</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/doc/src/erl_tar.xml b/lib/stdlib/doc/src/erl_tar.xml
index 0fa5a55c5b..898b55df72 100644
--- a/lib/stdlib/doc/src/erl_tar.xml
+++ b/lib/stdlib/doc/src/erl_tar.xml
@@ -442,7 +442,7 @@
structure like a file descriptor, a sftp channel id or such. The different <c>Fun</c>
clauses operates on that very term.
</p>
- <p>The fun clauses parameter lists are:
+ <p>The fun clauses parameter lists are:</p>
<taglist>
<tag><c>(write, {UserPrivate,DataToWrite})</c></tag>
<item>Write the term <c>DataToWrite</c> using <c>UserPrivate</c></item>
@@ -457,7 +457,6 @@
<tag><c></c></tag>
<item></item>
</taglist>
- </p>
<p>A complete <c>Fun</c> parameter for reading and writing on files using the
<seealso marker="kernel:file">file module</seealso> could be:
</p>
diff --git a/lib/stdlib/doc/src/ets.xml b/lib/stdlib/doc/src/ets.xml
index 03b995e4de..7b01109ff8 100644
--- a/lib/stdlib/doc/src/ets.xml
+++ b/lib/stdlib/doc/src/ets.xml
@@ -132,9 +132,10 @@
<name name="access"/>
</datatype>
<datatype>
- <name><marker id="type-continuation">continuation()</marker></name>
+ <name>continuation()</name>
<desc>
- <p>Opaque continuation used by <seealso marker="#select/1">
+ <p><marker id="type-continuation"/>
+ Opaque continuation used by <seealso marker="#select/1">
<c>select/1,3</c></seealso>, <seealso marker="#select_reverse/1">
<c>select_reverse/1,3</c></seealso>, <seealso
marker="#match/1">
@@ -448,13 +449,13 @@ Error: fun containing local Erlang function calls
<item><c>{owner, pid()}</c> <br></br>
The pid of the owner of the table.</item>
- <item><c>{protection, <seealso marker="#type-access">access()</seealso>}</c> <br></br>
+ <item><c>{protection, </c><seealso marker="#type-access">access()</seealso><c>}</c> <br></br>
The table access rights.</item>
<item><c>{size, integer() >= 0</c> <br></br>
The number of objects inserted in the table.</item>
- <item><c>{type, <seealso marker="#type-type">type()</seealso>}</c> <br></br>
+ <item><c>{type, </c><seealso marker="#type-type">type()</seealso><c>}</c> <br></br>
The table type.</item>
<item><c>{read_concurrency, boolean()}</c> <br></br>
@@ -916,7 +917,7 @@ ets:select(Table,MatchSpec),</code>
</item>
<item>
<p><c>{keypos,<anno>Pos</anno>}</c>
- Specfies which element in the stored tuples should be
+ Specifies which element in the stored tuples should be
used as key. By default, it is the first element, i.e.
<c><anno>Pos</anno>=1</c>. However, this is not always appropriate. In
particular, we do not want the first element to be the
@@ -1626,6 +1627,7 @@ true</pre>
<name name="update_counter" arity="4" clause_i="2"/>
<name name="update_counter" arity="3" clause_i="3"/>
<name name="update_counter" arity="4" clause_i="3"/>
+ <fsummary>Update a counter object in an ETS table.</fsummary>
<type variable="Tab"/>
<type variable="Key"/>
<type variable="UpdateOp" name_i="1"/>
@@ -1633,7 +1635,6 @@ true</pre>
<type variable="Threshold" name_i="1"/>
<type variable="SetValue" name_i="1"/>
<type variable="Default"/>
- <fsummary>Update a counter object in an ETS table.</fsummary>
<desc>
<p>This function provides an efficient way to update one or more
counters, without the hassle of having to look up an object, update
@@ -1700,11 +1701,11 @@ true</pre>
<func>
<name name="update_element" arity="3" clause_i="1"/>
<name name="update_element" arity="3" clause_i="2"/>
+ <fsummary>Updates the <c>Pos</c>:th element of the object with a given key in an ETS table.</fsummary>
<type variable="Tab"/>
<type variable="Key"/>
<type variable="Value"/>
<type variable="Pos"/>
- <fsummary>Updates the <c>Pos</c>:th element of the object with a given key in an ETS table.</fsummary>
<desc>
<p>This function provides an efficient way to update one or more
elements within an object, without the hassle of having to look up,
diff --git a/lib/stdlib/doc/src/file_sorter.xml b/lib/stdlib/doc/src/file_sorter.xml
index 30e09c17b0..f033eebec7 100644
--- a/lib/stdlib/doc/src/file_sorter.xml
+++ b/lib/stdlib/doc/src/file_sorter.xml
@@ -223,82 +223,82 @@ output(L) ->
<datatypes>
<datatype>
- <name name="file_name"/><br/>
+ <name name="file_name"/>
</datatype>
<datatype>
- <name name="file_names"/><br/>
+ <name name="file_names"/>
</datatype>
<datatype>
- <name name="i_command"/><br/>
+ <name name="i_command"/>
</datatype>
<datatype>
- <name name="i_reply"/><br/>
+ <name name="i_reply"/>
</datatype>
<datatype>
- <name name="infun"/><br/>
+ <name name="infun"/>
</datatype>
<datatype>
- <name name="input"/><br/>
+ <name name="input"/>
</datatype>
<datatype>
- <name name="input_reply"/><br/>
+ <name name="input_reply"/>
</datatype>
<datatype>
- <name name="o_command"/><br/>
+ <name name="o_command"/>
</datatype>
<datatype>
- <name name="o_reply"/><br/>
+ <name name="o_reply"/>
</datatype>
<datatype>
- <name name="object"/><br/>
+ <name name="object"/>
</datatype>
<datatype>
- <name name="outfun"/><br/>
+ <name name="outfun"/>
</datatype>
<datatype>
- <name name="output"/><br/>
+ <name name="output"/>
</datatype>
<datatype>
- <name name="output_reply"/><br/>
+ <name name="output_reply"/>
</datatype>
<datatype>
- <name name="value"/><br/>
+ <name name="value"/>
</datatype>
<datatype>
- <name name="options"/><br/>
+ <name name="options"/>
</datatype>
<datatype>
- <name name="option"/><br/>
+ <name name="option"/>
</datatype>
<datatype>
- <name name="format"/><br/>
+ <name name="format"/>
</datatype>
<datatype>
- <name name="format_fun"/><br/>
+ <name name="format_fun"/>
</datatype>
<datatype>
- <name name="header_length"/><br/>
+ <name name="header_length"/>
</datatype>
<datatype>
- <name name="key_pos"/><br/>
+ <name name="key_pos"/>
</datatype>
<datatype>
- <name name="no_files"/><br/>
+ <name name="no_files"/>
</datatype>
<datatype>
- <name name="order"/><br/>
+ <name name="order"/>
</datatype>
<datatype>
- <name name="order_fun"/><br/>
+ <name name="order_fun"/>
</datatype>
<datatype>
- <name name="size"/><br/>
+ <name name="size"/>
</datatype>
<datatype>
- <name name="tmp_directory"/><br/>
+ <name name="tmp_directory"/>
</datatype>
<datatype>
- <name name="reason"/><br/>
+ <name name="reason"/>
</datatype>
</datatypes>
diff --git a/lib/stdlib/doc/src/gen_event.xml b/lib/stdlib/doc/src/gen_event.xml
index 1efac1535a..c4bab45781 100644
--- a/lib/stdlib/doc/src/gen_event.xml
+++ b/lib/stdlib/doc/src/gen_event.xml
@@ -716,7 +716,7 @@ gen_event:stop -----> Module:terminate/2
the purposes described below.</p>
</note>
<p>This function is called by a gen_event process when:</p>
- <list typed="bulleted">
+ <list type="bulleted">
<item>One
of <seealso marker="sys#get_status/1">sys:get_status/1,2</seealso>
is invoked to get the gen_event status. <c>Opt</c> is set
@@ -740,7 +740,7 @@ gen_event:stop -----> Module:terminate/2
customises the details of the current state of the event
handler. Any term is allowed for <c>Status</c>. The
gen_event module uses <c>Status</c> as follows:</p>
- <list typed="bulleted">
+ <list type="bulleted">
<item>When <c>sys:get_status/1,2</c> is called, gen_event
ensures that its return value contains <c>Status</c> in
place of the event handler's actual state term.</item>
diff --git a/lib/stdlib/doc/src/gen_fsm.xml b/lib/stdlib/doc/src/gen_fsm.xml
index a8d7fadeb4..4d594b8eb2 100644
--- a/lib/stdlib/doc/src/gen_fsm.xml
+++ b/lib/stdlib/doc/src/gen_fsm.xml
@@ -805,7 +805,7 @@ gen_fsm:sync_send_all_state_event -----> Module:handle_sync_event/4
module state data.</p>
</note>
<p>This function is called by a gen_fsm process when:</p>
- <list typed="bulleted">
+ <list type="bulleted">
<item>One
of <seealso marker="sys#get_status/1">sys:get_status/1,2</seealso>
is invoked to get the gen_fsm status. <c>Opt</c> is set to
diff --git a/lib/stdlib/doc/src/gen_server.xml b/lib/stdlib/doc/src/gen_server.xml
index c31e869db8..6d04771cd4 100644
--- a/lib/stdlib/doc/src/gen_server.xml
+++ b/lib/stdlib/doc/src/gen_server.xml
@@ -673,7 +673,7 @@ gen_server:abcast -----> Module:handle_cast/2
module state.</p>
</note>
<p>This function is called by a gen_server process when:</p>
- <list typed="bulleted">
+ <list type="bulleted">
<item>One
of <seealso marker="sys#get_status/1">sys:get_status/1,2</seealso>
is invoked to get the gen_server status. <c>Opt</c> is set
diff --git a/lib/stdlib/doc/src/io.xml b/lib/stdlib/doc/src/io.xml
index edf3c51b4c..4655c8662f 100644
--- a/lib/stdlib/doc/src/io.xml
+++ b/lib/stdlib/doc/src/io.xml
@@ -132,8 +132,8 @@
<func>
<name name="get_chars" arity="2"/>
<name name="get_chars" arity="3"/>
- <type name="server_no_data"/>
<fsummary>Read a specified number of characters</fsummary>
+ <type name="server_no_data"/>
<desc>
<p>Reads <c><anno>Count</anno></c> characters from standard input
(<c><anno>IoDevice</anno></c>), prompting it with <c><anno>Prompt</anno></c>. It
@@ -162,8 +162,8 @@
<func>
<name name="get_line" arity="1"/>
<name name="get_line" arity="2"/>
- <type name="server_no_data"/>
<fsummary>Read a line</fsummary>
+ <type name="server_no_data"/>
<desc>
<p>Reads a line from the standard input (<c><anno>IoDevice</anno></c>),
prompting it with <c><anno>Prompt</anno></c>. It returns:</p>
@@ -300,8 +300,8 @@
<func>
<name name="read" arity="1"/>
<name name="read" arity="2"/>
- <type name="server_no_data"/>
<fsummary>Read a term</fsummary>
+ <type name="server_no_data"/>
<desc>
<p>Reads a term <c><anno>Term</anno></c> from the standard input
(<c><anno>IoDevice</anno></c>), prompting it with <c><anno>Prompt</anno></c>. It
@@ -330,8 +330,8 @@
<func>
<name name="read" arity="3"/>
<name name="read" arity="4"/>
- <type name="server_no_data"/>
<fsummary>Read a term</fsummary>
+ <type name="server_no_data"/>
<desc>
<p>Reads a term <c><anno>Term</anno></c> from <c><anno>IoDevice</anno></c>, prompting it
with <c><anno>Prompt</anno></c>. Reading starts at location
@@ -698,8 +698,8 @@ ok
<func>
<name name="fread" arity="2"/>
<name name="fread" arity="3"/>
- <type name="server_no_data"/>
<fsummary>Read formatted input</fsummary>
+ <type name="server_no_data"/>
<desc>
<p>Reads characters from the standard input (<c><anno>IoDevice</anno></c>),
prompting it with <c><anno>Prompt</anno></c>. Interprets the characters in
@@ -870,8 +870,8 @@ enter><input>:</input> <input>alan</input> <input>:</input> <input>joe</in
<name name="scan_erl_exprs" arity="2"/>
<name name="scan_erl_exprs" arity="3"/>
<name name="scan_erl_exprs" arity="4"/>
- <type name="server_no_data"/>
<fsummary>Read and tokenize Erlang expressions</fsummary>
+ <type name="server_no_data"/>
<desc>
<p>Reads data from the standard input (<c>IoDevice</c>),
prompting it with <c>Prompt</c>. Reading starts at location
@@ -919,8 +919,8 @@ enter><input>1.0er.</input>
<name name="scan_erl_form" arity="2"/>
<name name="scan_erl_form" arity="3"/>
<name name="scan_erl_form" arity="4"/>
- <type name="server_no_data"/>
<fsummary>Read and tokenize an Erlang form</fsummary>
+ <type name="server_no_data"/>
<desc>
<p>Reads data from the standard input (<c><anno>IoDevice</anno></c>),
prompting it with <c><anno>Prompt</anno></c>. Starts reading
@@ -939,9 +939,9 @@ enter><input>1.0er.</input>
<name name="parse_erl_exprs" arity="2"/>
<name name="parse_erl_exprs" arity="3"/>
<name name="parse_erl_exprs" arity="4"/>
+ <fsummary>Read, tokenize and parse Erlang expressions</fsummary>
<type name="parse_ret"/>
<type name="server_no_data"/>
- <fsummary>Read, tokenize and parse Erlang expressions</fsummary>
<desc>
<p>Reads data from the standard input
(<c><anno>IoDevice</anno></c>), prompting it with
@@ -990,9 +990,9 @@ enter><input>abc("hey".</input>
<name name="parse_erl_form" arity="2"/>
<name name="parse_erl_form" arity="3"/>
<name name="parse_erl_form" arity="4"/>
+ <fsummary>Read, tokenize and parse an Erlang form</fsummary>
<type name="parse_form_ret"/>
<type name="server_no_data"/>
- <fsummary>Read, tokenize and parse an Erlang form</fsummary>
<desc>
<p>Reads data from the standard input (<c><anno>IoDevice</anno></c>),
prompting it with <c><anno>Prompt</anno></c>. Starts reading at
diff --git a/lib/stdlib/doc/src/lists.xml b/lib/stdlib/doc/src/lists.xml
index 46edd9fe16..89ba5238b5 100644
--- a/lib/stdlib/doc/src/lists.xml
+++ b/lib/stdlib/doc/src/lists.xml
@@ -283,8 +283,8 @@ flatmap(Fun, List1) ->
</func>
<func>
<name name="keyfind" arity="3"/>
- <type_desc variable="N">1..tuple_size(<anno>Tuple</anno>)</type_desc>
<fsummary>Search for an element in a list of tuples</fsummary>
+ <type_desc variable="N">1..tuple_size(<anno>Tuple</anno>)</type_desc>
<desc>
<p>Searches the list of tuples <c><anno>TupleList</anno></c> for a
tuple whose <c><anno>N</anno></c>th element compares equal to <c><anno>Key</anno></c>.
@@ -311,8 +311,8 @@ flatmap(Fun, List1) ->
</func>
<func>
<name name="keymember" arity="3"/>
- <type_desc variable="N">1..tuple_size(<anno>Tuple</anno>)</type_desc>
<fsummary>Test for membership of a list of tuples</fsummary>
+ <type_desc variable="N">1..tuple_size(<anno>Tuple</anno>)</type_desc>
<desc>
<p>Returns <c>true</c> if there is a tuple in <c><anno>TupleList</anno></c>
whose <c><anno>N</anno></c>th element compares equal to <c><anno>Key</anno></c>, otherwise
@@ -346,8 +346,8 @@ flatmap(Fun, List1) ->
</func>
<func>
<name name="keysearch" arity="3"/>
- <type_desc variable="N">1..tuple_size(<anno>Tuple</anno>)</type_desc>
<fsummary>Search for an element in a list of tuples</fsummary>
+ <type_desc variable="N">1..tuple_size(<anno>Tuple</anno>)</type_desc>
<desc>
<p>Searches the list of tuples <c><anno>TupleList</anno></c> for a
tuple whose <c><anno>N</anno></c>th element compares equal to <c><anno>Key</anno></c>.
diff --git a/lib/stdlib/doc/src/math.xml b/lib/stdlib/doc/src/math.xml
index 31e838d741..aee6c3f238 100644
--- a/lib/stdlib/doc/src/math.xml
+++ b/lib/stdlib/doc/src/math.xml
@@ -72,9 +72,9 @@
<name name="log10" arity="1"/>
<name name="pow" arity="2"/>
<name name="sqrt" arity="1"/>
+ <fsummary>Diverse math functions</fsummary>
<type variable="X" name_i="7"/>
<type variable="Y" name_i="7"/>
- <fsummary>Diverse math functions</fsummary>
<desc>
<p>A collection of math functions which return floats. Arguments
are numbers. </p>
diff --git a/lib/stdlib/doc/src/notes.xml b/lib/stdlib/doc/src/notes.xml
index bdd0680038..267a993a1b 100644
--- a/lib/stdlib/doc/src/notes.xml
+++ b/lib/stdlib/doc/src/notes.xml
@@ -31,6 +31,67 @@
</header>
<p>This document describes the changes made to the STDLIB application.</p>
+<section><title>STDLIB 2.7</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>The Erlang Pretty Printer uses <c>::</c> for function
+ type constraints.</p> <p>A bug concerning pretty printing
+ of annotated type union elements in map pair types has
+ been fixed.</p> <p>Some minor issues regarding the
+ documentation of types and specs have been corrected.</p>
+ <p>
+ Own Id: OTP-13084</p>
+ </item>
+ <item>
+ <p> The shell command <c>rp</c> prints strings as lists
+ of integers if pretty printing of lists is set to
+ <c>false</c>. </p>
+ <p>
+ Own Id: OTP-13145</p>
+ </item>
+ <item>
+ <p>
+ The shell would crash if a bit syntax expression with
+ conflicting types were given (e.g. if a field type was
+ given as '<c>integer-binary</c>'). (Thanks to Aleksei
+ Magusev for reporting this bug.)</p>
+ <p>
+ Own Id: OTP-13157</p>
+ </item>
+ <item>
+ <p>The <c>rand:export_seed/0</c> would never return
+ '<c>undefined</c>' even if no seed has previously been
+ created. Fixed to return '<c>undefined</c>' if there is
+ no seed in the process dictionary.</p>
+ <p>
+ Own Id: OTP-13162</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Add support for the Delete, Home and End keys in the
+ Erlang shell.</p>
+ <p>
+ Own Id: OTP-13032</p>
+ </item>
+ <item>
+ <p><c>beam_lib:all_chunks/1</c> and
+ <c>beam_lib:build_module/1</c> have been documented.</p>
+ <p>
+ Own Id: OTP-13063</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>STDLIB 2.6</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -154,8 +215,9 @@
Correct <c>maps</c> module error exceptions </p>
<p>
Bad input to maps module function will now yield the
- following exceptions: <list> <item>{badmap,NotMap}
- or,</item> <item>badarg</item> </list></p>
+ following exceptions:</p>
+ <list> <item>{badmap, NotMap}, or </item> <item>badarg.</item>
+ </list>
<p>
Own Id: OTP-12657</p>
</item>
@@ -253,12 +315,11 @@
<p>
<c>proc_lib:stop/1,3</c> is used by the following
functions:</p>
- <p>
<list> <item><c>gen_server:stop/1,3</c> (new)</item>
<item><c>gen_fsm:stop/1,3</c> (new)</item>
<item><c>gen_event:stop/1,3</c> (modified to be
synchronous)</item> <item><c>wx_object:stop/1,3</c>
- (new)</item> </list></p>
+ (new)</item> </list>
<p>
Own Id: OTP-11173 Aux Id: seq12353 </p>
</item>
@@ -865,8 +926,7 @@
also implemented by the generic behaviours
<c>gen_server</c>, <c>gen_event</c> and <c>gen_fsm</c>.</p>
<p>
- The potential incompatibility refers to</p>
- <p>
+ The potential incompatibility refers to:</p>
<list> <item>The previous behaviour of intercepting the
system message and passing a tuple of size 2 as the last
argument to <c>sys:handle_system_msg/6</c> is no longer
@@ -874,7 +934,7 @@
<c>StateFun</c> in <c>sys:replace_state/2,3</c> fails is
changed from being totally silent to possibly (if the
callback module does not catch) throw an exception in the
- client process.</item> </list></p>
+ client process.</item> </list>
<p>
(Thanks to James Fish and Steve Vinoski)</p>
<p>
@@ -1036,22 +1096,28 @@
<p>
EEP43: New data type - Maps</p>
<p>
- With Maps you may for instance: <taglist> <item><c>M0 =
- #{ a =&gt; 1, b =&gt; 2}, % create
- associations</c></item> <item><c>M1 = M0#{ a := 10 }, %
- update values</c></item> <item><c>M2 = M1#{ "hi" =&gt;
- "hello"}, % add new associations</c></item> <item><c>#{
- "hi" := V1, a := V2, b := V3} = M2. % match keys with
- values</c></item> </taglist></p>
+ With Maps you may for instance:</p>
+ <taglist>
+ <tag/> <item><c>M0 = #{ a =&gt; 1, b =&gt; 2}, % create
+ associations</c></item>
+ <tag/><item><c>M1 = M0#{ a := 10 }, % update values</c></item>
+ <tag/><item><c>M2 = M1#{ "hi" =&gt;
+ "hello"}, % add new associations</c></item>
+ <tag/><item><c>#{ "hi" := V1, a := V2, b := V3} = M2.
+ % match keys with values</c></item>
+ </taglist>
<p>
For information on how to use Maps please see Map Expressions in the
<seealso marker="doc/reference_manual:expressions#map_expressions">
Reference Manual</seealso>.</p>
<p>
The current implementation is without the following
- features: <taglist> <item>No variable keys</item>
- <item>No single value access</item> <item>No map
- comprehensions</item> </taglist></p>
+ features:</p>
+ <taglist>
+ <tag/><item>No variable keys</item>
+ <tag/><item>No single value access</item>
+ <tag/><item>No map comprehensions</item>
+ </taglist>
<p>
Note that Maps is <em>experimental</em> during OTP 17.0.</p>
<p>
@@ -1802,13 +1868,15 @@
supervisor or for the problematic child.</p>
<p>
This introduces some incompatibilities in stdlib due to
- new return values from supervisor: <list>
+ new return values from supervisor:</p>
+ <list>
<item>restart_child/2 can now return
{error,restarting}</item> <item>delete_child/2 can now
return {error,restarting}</item> <item>which_children/1
returns a list of {Id,Child,Type,Mods}, where Child, in
addition to the old pid() or 'undefined', now also can be
- 'restarting'.</item> </list></p>
+ 'restarting'.</item>
+ </list>
<p>
*** POTENTIAL INCOMPATIBILITY ***</p>
<p>
@@ -1824,10 +1892,10 @@
Own Id: OTP-9782 Aux Id: seq11964 </p>
</item>
<item>
- <p> Use universal time as base in error logger
+ <p> Use universal time as base in error logger</p>
<p>
Previous conversion used the deprecated
- calendar:local_time_to_universal_time/1 </p></p>
+ calendar:local_time_to_universal_time/1 </p>
<p>
Own Id: OTP-9854</p>
</item>
@@ -2584,10 +2652,10 @@
Own Id: OTP-8989 Aux Id: seq11741 </p>
</item>
<item>
- <p>Fix exception generation in the io module
+ <p>Fix exception generation in the io module</p>
<p>
Some functions did not generate correct badarg exception
- on a badarg exception.</p></p>
+ on a badarg exception.</p>
<p>
Own Id: OTP-9045</p>
</item>
diff --git a/lib/stdlib/doc/src/rand.xml b/lib/stdlib/doc/src/rand.xml
index e7d4728ef7..50057259c6 100644
--- a/lib/stdlib/doc/src/rand.xml
+++ b/lib/stdlib/doc/src/rand.xml
@@ -104,7 +104,7 @@
strong. If a strong cryptographic random number generator is
needed, use one of functions in the
<seealso marker="crypto:crypto">crypto</seealso>
- module, for example <c>crypto:rand_bytes/1</c>.</p></note>
+ module, for example <c>crypto:strong_rand_bytes/1</c>.</p></note>
</description>
<datatypes>
<datatype>
diff --git a/lib/stdlib/doc/src/random.xml b/lib/stdlib/doc/src/random.xml
index 91a4012ce9..fc4f796863 100644
--- a/lib/stdlib/doc/src/random.xml
+++ b/lib/stdlib/doc/src/random.xml
@@ -48,7 +48,7 @@
tuple of three integers.</p>
<p>It should be noted that this random number generator is not cryptographically
strong. If a strong cryptographic random number generator is needed for
- example <c>crypto:rand_bytes/1</c> could be used instead.</p>
+ example <c>crypto:strong_rand_bytes/1</c> could be used instead.</p>
<note><p>The new and improved <seealso
marker="stdlib:rand">rand</seealso> module should be used
instead of this module.</p></note>
@@ -76,9 +76,15 @@
dictionary, and returns the old state.</p>
<p>One easy way of obtaining a unique value to seed with is to:</p>
<code type="none">
- random:seed(<seealso marker="erts:erlang#phash2/1">erlang:phash2</seealso>([<seealso marker="erts:erlang#node/0">node()</seealso>]),
- <seealso marker="erts:erlang#monotonic_time/0">erlang:monotonic_time()</seealso>,
- <seealso marker="erts:erlang#unique_integer/0">erlang:unique_integer()</seealso>)</code>
+random:seed(erlang:phash2([node()]),
+ erlang:monotonic_time(),
+ erlang:unique_integer())</code>
+ <p>See <seealso marker="erts:erlang#phash2/1">
+ erlang:phash2/1</seealso>, <seealso marker="erts:erlang#node/0">
+ node/0</seealso>, <seealso marker="erts:erlang#monotonic_time/0">
+ erlang:monotonic_time/0</seealso>, and
+ <seealso marker="erts:erlang#unique_integer/0">
+ erlang:unique_integer/0</seealso>) for details.</p>
</desc>
</func>
<func>
@@ -142,7 +148,7 @@
<p>The implementation changed in R15. Upgrading to R15 will break
applications that expect a specific output for a given seed. The output
is still deterministic number series, but different compared to releases
- older than R15. The seed <c>{0,0,0}</c> will for example no longer
+ older than R15. The seed <c>{0,0,0}</c> will, for example, no longer
produce a flawed series of only zeros.</p>
</section>
</erlref>
diff --git a/lib/stdlib/doc/src/re.xml b/lib/stdlib/doc/src/re.xml
index 46b382a6be..8c19926b10 100644
--- a/lib/stdlib/doc/src/re.xml
+++ b/lib/stdlib/doc/src/re.xml
@@ -205,8 +205,8 @@ This option makes it possible to include comments inside complicated patterns. N
</func>
<func>
<name name="run" arity="3"/>
- <type_desc variable="CompileOpt">See <seealso marker="#compile_options">compile/2</seealso> above.</type_desc>
<fsummary>Match a subject against regular expression and capture subpatterns</fsummary>
+ <type_desc variable="CompileOpt">See <seealso marker="#compile_options">compile/2</seealso> above.</type_desc>
<desc>
<p>Executes a regexp matching, returning <c>match/{match,
@@ -881,11 +881,11 @@ nomatch
</desc>
</func>
</funcs>
-
- <marker id="regexp_syntax"></marker>
+
<section>
<title>PERL LIKE REGULAR EXPRESSIONS SYNTAX</title>
- <p>The following sections contain reference material for the
+ <p><marker id="regexp_syntax"></marker>
+ The following sections contain reference material for the
regular expressions used by this module. The regular expression
reference is based on the PCRE documentation, with changes in
cases where the re module behaves differently to the PCRE library.</p>
@@ -2070,7 +2070,7 @@ supported, and an error is given if they are encountered.</p>
<p>By default, in UTF modes, characters with values greater than 255 do not match
any of the POSIX character classes. However, if the PCRE_UCP option is passed
-to <b>pcre_compile()</b>, some of the classes are changed so that Unicode
+to <em>pcre_compile()</em>, some of the classes are changed so that Unicode
character properties are used. This is achieved by replacing the POSIX classes
by other sequences, as follows:</p>
@@ -2078,10 +2078,10 @@ by other sequences, as follows:</p>
<tag>[:alnum:]</tag> <item>becomes <em>\p{Xan}</em></item>
<tag>[:alpha:]</tag> <item>becomes <em>\p{L}</em></item>
<tag>[:blank:]</tag> <item>becomes <em>\h</em></item>
- <tag>[:digit:</tag>] <item>becomes <em>\p{Nd}</em></item>
+ <tag>[:digit:]</tag> <item>becomes <em>\p{Nd}</em></item>
<tag>[:lower:]</tag> <item>becomes <em>\p{Ll}</em></item>
<tag>[:space:]</tag> <item>becomes <em>\p{Xps}</em></item>
- <tag>[:upper:</tag>] <item>becomes <em>\p{Lu}</em></item>
+ <tag>[:upper:]</tag> <item>becomes <em>\p{Lu}</em></item>
<tag>[:word:]</tag> <item>becomes <em>\p{Xwd}</em></item>
</taglist>
@@ -3059,7 +3059,7 @@ default newline convention is in force:</p>
<quote><p> abc #comment \n still comment</p></quote>
-<p>On encountering the # character, <b>pcre_compile()</b> skips along, looking for
+<p>On encountering the # character, <em>pcre_compile()</em> skips along, looking for
a newline in the pattern. The sequence \n is still literal at this stage, so
it does not terminate the comment. Only an actual character with the code value
0x0a (the default newline) does so.</p>
diff --git a/lib/stdlib/doc/src/sofs.xml b/lib/stdlib/doc/src/sofs.xml
index 5d7648d9a1..53f6ca957a 100644
--- a/lib/stdlib/doc/src/sofs.xml
+++ b/lib/stdlib/doc/src/sofs.xml
@@ -398,8 +398,9 @@ fun(S) -> sofs:partition(1, S) end
</datatype>
<datatype>
<!-- Parameterized opaque types are NYI: -->
- <name><marker id="type-tuple_of">tuple_of(T)</marker></name>
- <desc><p>A tuple where the elements are of type <c>T</c>.</p></desc>
+ <name>tuple_of(T)</name>
+ <desc><p><marker id="type-tuple_of"/>
+ A tuple where the elements are of type <c>T</c>.</p></desc>
</datatype>
</datatypes>
<funcs>
diff --git a/lib/stdlib/doc/src/supervisor.xml b/lib/stdlib/doc/src/supervisor.xml
index f08b752998..24ff251ce3 100644
--- a/lib/stdlib/doc/src/supervisor.xml
+++ b/lib/stdlib/doc/src/supervisor.xml
@@ -353,7 +353,7 @@
<desc>
<p>Dynamically adds a child specification to the supervisor
<c><anno>SupRef</anno></c> which starts the corresponding child process.</p>
- <p><marker id="SupRef"><c><anno>SupRef</anno></c></marker> can be:</p>
+ <p><marker id="SupRef"/><c><anno>SupRef</anno></c> can be:</p>
<list type="bulleted">
<item>the pid,</item>
<item><c>Name</c>, if the supervisor is locally registered,</item>
diff --git a/lib/stdlib/doc/src/sys.xml b/lib/stdlib/doc/src/sys.xml
index 6ec515849e..d400f72e1d 100644
--- a/lib/stdlib/doc/src/sys.xml
+++ b/lib/stdlib/doc/src/sys.xml
@@ -238,8 +238,8 @@
<p>These functions are intended only to help with debugging. They are provided for
convenience, allowing developers to avoid having to create their own state extraction
functions and also avoid having to interactively extract state from the return values of
- <c><seealso marker="#get_status-1">get_status/1</seealso></c> or
- <c><seealso marker="#get_status-2">get_status/2</seealso></c> while debugging.</p>
+ <seealso marker="#get_status-1"><c>get_status/1</c></seealso> or
+ <seealso marker="#get_status-2"><c>get_status/2</c></seealso> while debugging.</p>
</note>
<p>The value of <c><anno>State</anno></c> varies for different types of
processes. For a <c>gen_server</c> process, the returned <c><anno>State</anno></c>
diff --git a/lib/stdlib/doc/src/timer.xml b/lib/stdlib/doc/src/timer.xml
index e002f519b9..7609487300 100644
--- a/lib/stdlib/doc/src/timer.xml
+++ b/lib/stdlib/doc/src/timer.xml
@@ -85,7 +85,6 @@
<name name="send_after" arity="3"/>
<fsummary>Send <c>Message</c>to <c>Pid</c>after a specified <c>Time</c>.</fsummary>
<desc>
- <p>
<taglist>
<tag><c>send_after/3</c></tag>
<item>
@@ -99,7 +98,6 @@
<p>Same as <c>send_after(<anno>Time</anno>, self(), <anno>Message</anno>)</c>.</p>
</item>
</taglist>
- </p>
</desc>
</func>
<func>
@@ -109,7 +107,6 @@
<name name="exit_after" arity="3"/>
<fsummary>Send an exit signal with <c>Reason</c>after a specified <c>Time</c>.</fsummary>
<desc>
- <p>
<taglist>
<tag><c>exit_after/3</c></tag>
<item>
@@ -130,7 +127,6 @@
<p>Same as <c>exit_after(<anno>Time</anno>, self(), kill)</c>. </p>
</item>
</taglist>
- </p>
</desc>
</func>
<func>
@@ -147,7 +143,6 @@
<name name="send_interval" arity="3"/>
<fsummary>Send <c>Message</c>repeatedly at intervals of <c>Time</c>.</fsummary>
<desc>
- <p>
<taglist>
<tag><c>send_interval/3</c></tag>
<item>
@@ -161,7 +156,6 @@
<p>Same as <c>send_interval(<anno>Time</anno>, self(), <anno>Message</anno>)</c>.</p>
</item>
</taglist>
- </p>
</desc>
</func>
<func>
@@ -192,7 +186,6 @@
Function, Arguments)</c> or <c>apply(Fun, Arguments)</c></fsummary>
<type_desc variable="Time">In microseconds</type_desc>
<desc>
- <p>
<taglist>
<tag><c>tc/3</c></tag>
<item>
@@ -213,7 +206,6 @@
</item>
</taglist>
- </p>
</desc>
</func>
<func>
diff --git a/lib/stdlib/doc/src/unicode.xml b/lib/stdlib/doc/src/unicode.xml
index 19ddf1cbd6..966eec49f5 100644
--- a/lib/stdlib/doc/src/unicode.xml
+++ b/lib/stdlib/doc/src/unicode.xml
@@ -133,7 +133,7 @@
<c>latin1</c>, or have characters encoded as one of the
UTF-encodings, which is given as the <c><anno>InEncoding</anno></c>
parameter. Only when the <c><anno>InEncoding</anno></c> is one of the UTF
- encodings, integers in the list are allowed to be grater than
+ encodings, integers in the list are allowed to be greater than
255.</p>
<p>If <c><anno>InEncoding</anno></c> is <c>latin1</c>, the <c><anno>Data</anno></c> parameter
diff --git a/lib/stdlib/doc/src/zip.xml b/lib/stdlib/doc/src/zip.xml
index 4500995c34..186c8ac724 100644
--- a/lib/stdlib/doc/src/zip.xml
+++ b/lib/stdlib/doc/src/zip.xml
@@ -126,7 +126,7 @@
</datatype>
<datatype>
<name name="filename"/>
- <p>The name of a zip file.</p>
+ <desc><p>The name of a zip file.</p></desc>
</datatype>
<datatype><name name="extension"/></datatype>
<datatype><name name="extension_spec"/></datatype>
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 b93ce97cd3..6e00401dce 100644
--- a/lib/stdlib/src/beam_lib.erl
+++ b/lib/stdlib/src/beam_lib.erl
@@ -308,6 +308,17 @@ make_crypto_key(des3_cbc=Type, String) ->
<<K3:8/binary,IVec:8/binary>> = erlang:md5([First|reverse(String)]),
{Type,[K1,K2,K3],IVec,8}.
+-spec build_module(Chunks) -> {'ok', Binary} when
+ Chunks :: [{chunkid(), dataB()}],
+ Binary :: binary().
+
+build_module(Chunks0) ->
+ Chunks = list_to_binary(build_chunks(Chunks0)),
+ Size = byte_size(Chunks),
+ 0 = Size rem 4, % Assertion: correct padding?
+ {ok, <<"FOR1", (Size+4):32, "BEAM", Chunks/binary>>}.
+
+
%%
%% Local functions
%%
@@ -419,12 +430,6 @@ strip_file(File) ->
end
end.
-build_module(Chunks0) ->
- Chunks = list_to_binary(build_chunks(Chunks0)),
- Size = byte_size(Chunks),
- 0 = Size rem 4, % Assertion: correct padding?
- {ok, <<"FOR1", (Size+4):32, "BEAM", Chunks/binary>>}.
-
build_chunks([{Id, Data} | Chunks]) ->
BId = list_to_binary(Id),
Size = byte_size(Data),
@@ -867,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/edlin.erl b/lib/stdlib/src/edlin.erl
index 8c7a984f1c..19444c0502 100644
--- a/lib/stdlib/src/edlin.erl
+++ b/lib/stdlib/src/edlin.erl
@@ -227,6 +227,8 @@ key_map($F, meta_o) -> end_of_line;
key_map($\177, none) -> backward_delete_char;
key_map($\177, meta) -> backward_kill_word;
key_map($[, meta) -> meta_left_sq_bracket;
+key_map($H, meta_left_sq_bracket) -> beginning_of_line;
+key_map($F, meta_left_sq_bracket) -> end_of_line;
key_map($D, meta_left_sq_bracket) -> backward_char;
key_map($C, meta_left_sq_bracket) -> forward_char;
% support a few <CTRL>+<CURSOR LEFT|RIGHT> combinations...
@@ -237,8 +239,10 @@ key_map($[, meta_meta) -> meta_csi;
key_map($C, meta_csi) -> forward_word;
key_map($D, meta_csi) -> backward_word;
key_map($1, meta_left_sq_bracket) -> {csi, "1"};
+key_map($3, meta_left_sq_bracket) -> {csi, "3"};
key_map($5, meta_left_sq_bracket) -> {csi, "5"};
key_map($5, {csi, "1;"}) -> {csi, "1;5"};
+key_map($~, {csi, "3"}) -> forward_delete_char;
key_map($C, {csi, "5"}) -> forward_word;
key_map($C, {csi, "1;5"}) -> forward_word;
key_map($D, {csi, "5"}) -> backward_word;
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_eval.erl b/lib/stdlib/src/erl_eval.erl
index ca3cc43b19..568eb1c852 100644
--- a/lib/stdlib/src/erl_eval.erl
+++ b/lib/stdlib/src/erl_eval.erl
@@ -1184,7 +1184,7 @@ match_tuple([], _, _, Bs, _BBs) ->
match_map([{map_field_exact, _, K, V}|Fs], Map, Bs0, BBs) ->
Vm = try
- {value, Ke, _} = expr(K, Bs0),
+ {value, Ke, _} = expr(K, BBs),
maps:get(Ke,Map)
catch error:_ ->
throw(nomatch)
diff --git a/lib/stdlib/src/erl_lint.erl b/lib/stdlib/src/erl_lint.erl
index c4cb5fdc80..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}) ->
@@ -293,6 +292,9 @@ format_error({variable_in_record_def,V}) ->
%% --- binaries ---
format_error({undefined_bittype,Type}) ->
io_lib:format("bit type ~w undefined", [Type]);
+format_error({bittype_mismatch,Val1,Val2,What}) ->
+ io_lib:format("conflict in ~s specification for bit field: '~p' and '~p'",
+ [What,Val1,Val2]);
format_error(bittype_unit) ->
"a bit unit size must not be specified unless a size is specified too";
format_error(illegal_bitsize) ->
@@ -371,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
@@ -413,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) ->
@@ -2873,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.
@@ -2887,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.
@@ -2924,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]} ->
@@ -2932,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() ->
@@ -3187,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 ->
@@ -3482,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.
@@ -3557,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
@@ -3567,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_pp.erl b/lib/stdlib/src/erl_pp.erl
index f7a969977a..c5177aca90 100644
--- a/lib/stdlib/src/erl_pp.erl
+++ b/lib/stdlib/src/erl_pp.erl
@@ -253,6 +253,8 @@ lattribute(import, Name, _Opts, _State) when is_list(Name) ->
attr("import", [{var,a0(),pname(Name)}]);
lattribute(import, {From,Falist}, _Opts, _State) ->
attr("import",[{var,a0(),pname(From)},falist(Falist)]);
+lattribute(export_type, Talist, _Opts, _State) ->
+ call({var,a0(),"-export_type"}, [falist(Talist)], 0, options(none));
lattribute(optional_callbacks, Falist, Opts, _State) ->
ArgL = try falist(Falist)
catch _:_ -> abstract(Falist, Opts)
@@ -321,7 +323,6 @@ ltype({type,_,'fun',[{type,_,any},_]}=FunType, _) ->
ltype({type,_Line,'fun',[{type,_,product,_},_]}=FunType, _) ->
[fun_type(['fun',$(], FunType),$)];
ltype({type,Line,T,Ts}, _) ->
- %% Compatibility. Before 18.0.
simple_type({atom,Line,T}, Ts);
ltype({user_type,Line,T,Ts}, _) ->
simple_type({atom,Line,T}, Ts);
@@ -346,16 +347,8 @@ map_type(Fs) ->
map_pair_types(Fs) ->
tuple_type(Fs, fun map_pair_type/2).
-map_pair_type({type,_Line,map_field_assoc,[Ktype,Vtype]}, Prec) ->
- map_assoc_typed(ltype(Ktype), Vtype, Prec).
-
-map_assoc_typed(B, {type,_,union,Ts}, Prec) ->
- {first,[B,$\s],{seq,[],[],[],map_assoc_union_type(Ts, Prec)}};
-map_assoc_typed(B, Type, Prec) ->
- {list,[{cstep,[B," =>"],ltype(Type, Prec)}]}.
-
-map_assoc_union_type([T|Ts], Prec) ->
- [[leaf("=> "),ltype(T)] | ltypes(Ts, fun union_elem/2, Prec)].
+map_pair_type({type,_Line,map_field_assoc,[KType,VType]}, Prec) ->
+ {list,[{cstep,[ltype(KType, Prec),leaf(" =>")],ltype(VType, Prec)}]}.
record_type(Name, Fields) ->
{first,[record_name(Name)],field_types(Fields)}.
@@ -370,9 +363,6 @@ typed(B, Type) ->
{_L,_P,R} = type_inop_prec('::'),
{list,[{cstep,[B,' ::'],ltype(Type, R)}]}.
-union_elem(T, Prec) ->
- [leaf(" | "),ltype(T, Prec)].
-
tuple_type(Ts, F) ->
{seq,${,$},[$,],ltypes(Ts, F, 0)}.
@@ -399,6 +389,9 @@ guard_type(Before, Gs) ->
Gl = {list,[{step,'when',expr_list(Gs, [$,], fun constraint/2, Opts)}]},
{list,[{step,Before,Gl}]}.
+constraint({type,_Line,constraint,[{atom,_,is_subtype},[{var,_,_}=V,Type]]},
+ _Opts) ->
+ typed(lexpr(V, options(none)), Type);
constraint({type,_Line,constraint,[Tag,As]}, _Opts) ->
simple_type(Tag, As).
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/rand.erl b/lib/stdlib/src/rand.erl
index 8e8d0bc801..dc060e82d9 100644
--- a/lib/stdlib/src/rand.erl
+++ b/lib/stdlib/src/rand.erl
@@ -63,7 +63,7 @@
%% Return algorithm and seed so that RNG state can be recreated with seed/1
-spec export_seed() -> undefined | export_state().
export_seed() ->
- case seed_get() of
+ case get(?SEED_DICT) of
{#{type:=Alg}, Seed} -> {Alg, Seed};
_ -> undefined
end.
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/shell.erl b/lib/stdlib/src/shell.erl
index f215a66812..ce1d9eb0ff 100644
--- a/lib/stdlib/src/shell.erl
+++ b/lib/stdlib/src/shell.erl
@@ -999,12 +999,7 @@ local_func(rl, [A], Bs0, _Shell, RT, Lf, Ef) ->
{value,list_records(record_defs(RT, listify(Recs))),Bs};
local_func(rp, [A], Bs0, _Shell, RT, Lf, Ef) ->
{[V],Bs} = expr_list([A], Bs0, Lf, Ef),
- Cs = io_lib_pretty:print(V, ([{column, 1},
- {line_length, columns()},
- {depth, -1},
- {max_chars, ?CHAR_MAX},
- {record_print_fun, record_print_fun(RT)}]
- ++ enc())),
+ Cs = pp(V, _Column=1, _Depth=-1, RT),
io:requests([{put_chars, unicode, Cs}, nl]),
{value,ok,Bs};
local_func(rr, [A], Bs0, _Shell, RT, Lf, Ef) ->
@@ -1397,9 +1392,9 @@ get_history_and_results() ->
{History, erlang:min(Results, History)}.
pp(V, I, RT) ->
- pp(V, I, RT, enc()).
+ pp(V, I, _Depth=?LINEMAX, RT).
-pp(V, I, RT, Enc) ->
+pp(V, I, D, RT) ->
Strings =
case application:get_env(stdlib, shell_strings) of
{ok, false} ->
@@ -1408,10 +1403,10 @@ pp(V, I, RT, Enc) ->
true
end,
io_lib_pretty:print(V, ([{column, I}, {line_length, columns()},
- {depth, ?LINEMAX}, {max_chars, ?CHAR_MAX},
+ {depth, D}, {max_chars, ?CHAR_MAX},
{strings, Strings},
{record_print_fun, record_print_fun(RT)}]
- ++ Enc)).
+ ++ enc())).
columns() ->
case io:columns() of
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/stdlib.appup.src b/lib/stdlib/src/stdlib.appup.src
index 5f61752655..04cdf31ada 100644
--- a/lib/stdlib/src/stdlib.appup.src
+++ b/lib/stdlib/src/stdlib.appup.src
@@ -18,9 +18,9 @@
%% %CopyrightEnd%
{"%VSN%",
%% Up from - max one major revision back
- [{<<"2\\.5(\\.[0-9]+)*">>,[restart_new_emulator]}, %% OTP-18.0.*
- {<<"2\\.[0-4](\\.[0-9]+)*">>,[restart_new_emulator]}], %% 17.0-17.5
+ [{<<"2\\.[5-7](\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-18.*
+ {<<"2\\.[0-4](\\.[0-9]+)*">>,[restart_new_emulator]}], % 17.0-17.5
%% Down to - max one major revision back
- [{<<"2\\.5(\\.[0-9]+)*">>,[restart_new_emulator]}, %% OTP-18.0.*
- {<<"2\\.[0-4](\\.[0-9]+)*">>,[restart_new_emulator]}] %% 17.0-17.5
+ [{<<"2\\.[5-7](\\.[0-9]+)*">>,[restart_new_emulator]}, % OTP-18.*
+ {<<"2\\.[0-4](\\.[0-9]+)*">>,[restart_new_emulator]}] % 17.0-17.5
}.
diff --git a/lib/stdlib/src/supervisor.erl b/lib/stdlib/src/supervisor.erl
index 3c77501c0f..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;
@@ -1083,7 +1087,7 @@ wait_dynamic_children(#child{restart_type=RType} = Child, Pids, Sz,
{timeout, TRef, kill} ->
?SETS:fold(fun(P, _) -> exit(P, kill) end, ok, Pids),
- wait_dynamic_children(Child, Pids, Sz-1, undefined, EStack)
+ wait_dynamic_children(Child, Pids, Sz, undefined, EStack)
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_eval_SUITE.erl b/lib/stdlib/test/erl_eval_SUITE.erl
index b9c4ad0a46..50fc62a00e 100644
--- a/lib/stdlib/test/erl_eval_SUITE.erl
+++ b/lib/stdlib/test/erl_eval_SUITE.erl
@@ -1483,6 +1483,16 @@ eep43(Config) when is_list(Config) ->
" #{ K1 := 1, K2 := 2, K3 := 3, {2,2} := 4} = Map "
"end.",
#{ 1 => 1, <<42:301>> => 2, {3,<<42:301>>} => 3, {2,2} => 4}),
+ check(fun () ->
+ X = key,
+ (fun(#{X := value}) -> true end)(#{X => value})
+ end,
+ "begin "
+ " X = key, "
+ " (fun(#{X := value}) -> true end)(#{X => value}) "
+ "end.",
+ true),
+
error_check("[camembert]#{}.", {badmap,[camembert]}),
error_check("[camembert]#{nonexisting:=v}.", {badmap,[camembert]}),
error_check("#{} = 1.", {badmatch,1}),
diff --git a/lib/stdlib/test/erl_lint_SUITE.erl b/lib/stdlib/test/erl_lint_SUITE.erl
index 0424e2b967..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.
@@ -3604,7 +3610,10 @@ bin_syntax_errors(Config) ->
t(<<X/unit:8>>) -> X;
t(<<X:7/float>>) -> X;
t(<< <<_:8>> >>) -> ok;
- t(<<(x ! y):8/integer>>) -> ok.
+ t(<<(x ! y):8/integer>>) -> ok;
+ t(X) ->
+ {<<X/binary-integer>>,<<X/signed-unsigned-integer>>,
+ <<X/little-big>>,<<X/unit:4-unit:8>>}.
">>,
[],
{error,[{1,erl_lint,illegal_bitsize},
@@ -3613,7 +3622,12 @@ bin_syntax_errors(Config) ->
{4,erl_lint,{undefined_bittype,bad_type}},
{5,erl_lint,bittype_unit},
{7,erl_lint,illegal_pattern},
- {8,erl_lint,illegal_pattern}],
+ {8,erl_lint,illegal_pattern},
+ {10,erl_lint,{bittype_mismatch,integer,binary,"type"}},
+ {10,erl_lint,{bittype_mismatch,unsigned,signed,"sign"}},
+ {11,erl_lint,{bittype_mismatch,8,4,"unit"}},
+ {11,erl_lint,{bittype_mismatch,big,little,"endianness"}}
+ ],
[{6,erl_lint,{bad_bitsize,"float"}}]}}
],
[] = run(Config, Ts),
@@ -3835,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) ->
@@ -3920,22 +3923,35 @@ run_test2(Conf, Test, Warnings0) ->
%% is no reason to produce an output file since we are only
%% interested in the errors and warnings.
- %% Print warnings, call erl_lint:format_error/1.
+ %% Print warnings, call erl_lint:format_error/1. (But note that
+ %% the compiler will ignore failing calls to erl_lint:format_error/1.)
compile:file(File, [binary,report|Opts]),
case compile:file(File, [binary|Opts]) of
- {ok, _M, Code, Ws} when is_binary(Code) -> warnings(File, Ws);
- {error, [{File,Es}], []} -> {errors, Es, []};
- {error, [{File,Es}], [{File,Ws}]} -> {error, Es, Ws};
- {error, [{File,Es1},{File,Es2}], []} -> {errors2, Es1, Es2}
+ {ok, _M, Code, Ws} when is_binary(Code) ->
+ warnings(File, Ws);
+ {error, [{File,Es}], []} ->
+ {errors, call_format_error(Es), []};
+ {error, [{File,Es}], [{File,Ws}]} ->
+ {error, call_format_error(Es), call_format_error(Ws)};
+ {error, [{File,Es1},{File,Es2}], []} ->
+ {errors2, Es1, Es2}
end.
warnings(File, Ws) ->
case lists:append([W || {F, W} <- Ws, F =:= File]) of
- [] -> [];
- L -> {warnings, L}
+ [] ->
+ [];
+ L ->
+ {warnings, call_format_error(L)}
end.
+call_format_error(L) ->
+ %% Smoke test of format_error/1 to make sure that no crashes
+ %% slip through.
+ _ = [Mod:format_error(Term) || {_,Mod,Term} <- L],
+ L.
+
fail() ->
io:format("failed~n"),
?t:fail().
diff --git a/lib/stdlib/test/erl_pp_SUITE.erl b/lib/stdlib/test/erl_pp_SUITE.erl
index 389fd059f6..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) ->
@@ -960,6 +965,9 @@ maps_syntax(Config) when is_list(Config) ->
"-compile(export_all).\n"
"-type t1() :: map().\n"
"-type t2() :: #{ atom() => integer(), atom() => float() }.\n"
+ "-type u() :: #{a => (I :: integer()) | (A :: atom()),\n"
+ " (X :: atom()) | (Y :: atom()) =>\n"
+ " (I :: integer()) | (A :: atom())}.\n"
"-spec f1(t1()) -> 'true'.\n"
"f1(M) when is_map(M) -> true.\n"
"-spec f2(t2()) -> integer().\n"
@@ -995,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">>,
@@ -1062,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/rand_SUITE.erl b/lib/stdlib/test/rand_SUITE.erl
index 111bf620de..03b5ce1a25 100644
--- a/lib/stdlib/test/rand_SUITE.erl
+++ b/lib/stdlib/test/rand_SUITE.erl
@@ -126,6 +126,9 @@ seed_1(Alg) ->
false = (S1 =:= rand:seed_s(Alg)),
%% Negative integers works
_ = rand:seed_s(Alg, {-1,-1,-1}),
+ %% Check that export_seed/1 returns 'undefined' if there is no seed
+ erase(rand_seed),
+ undefined = rand:export_seed(),
%% Other term do not work
{'EXIT', _} = (catch rand:seed_s(foobar, os:timestamp())),
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.
diff --git a/lib/stdlib/vsn.mk b/lib/stdlib/vsn.mk
index 3387d74e57..39b44c9104 100644
--- a/lib/stdlib/vsn.mk
+++ b/lib/stdlib/vsn.mk
@@ -1 +1 @@
-STDLIB_VSN = 2.6
+STDLIB_VSN = 2.7