aboutsummaryrefslogtreecommitdiffstats
path: root/lib/stdlib
diff options
context:
space:
mode:
Diffstat (limited to 'lib/stdlib')
-rw-r--r--lib/stdlib/doc/src/lists.xml8
-rw-r--r--lib/stdlib/doc/src/unicode_usage.xml44
-rw-r--r--lib/stdlib/src/edlin_expand.erl8
-rw-r--r--lib/stdlib/src/erl_lint.erl21
-rw-r--r--lib/stdlib/src/lists.erl15
-rw-r--r--lib/stdlib/test/edlin_expand_SUITE.erl11
-rw-r--r--lib/stdlib/test/erl_lint_SUITE.erl19
-rw-r--r--lib/stdlib/test/expand_test.erl6
-rw-r--r--lib/stdlib/test/expand_test1.erl4
-rw-r--r--lib/stdlib/test/lists_SUITE.erl12
10 files changed, 107 insertions, 41 deletions
diff --git a/lib/stdlib/doc/src/lists.xml b/lib/stdlib/doc/src/lists.xml
index 251a383cf8..ee3c51c62c 100644
--- a/lib/stdlib/doc/src/lists.xml
+++ b/lib/stdlib/doc/src/lists.xml
@@ -123,6 +123,14 @@
</desc>
</func>
<func>
+ <name name="droplast" arity="1"/>
+ <fsummary>Drop the last element of a list</fsummary>
+ <desc>
+ <p>Drops the last element of a <c><anno>List</anno></c>. The list should
+ be non-empty, otherwise the function will crash with a <c>function_clause</c></p>
+ </desc>
+ </func>
+ <func>
<name name="dropwhile" arity="2"/>
<fsummary>Drop elements from a list while a predicate is true</fsummary>
<desc>
diff --git a/lib/stdlib/doc/src/unicode_usage.xml b/lib/stdlib/doc/src/unicode_usage.xml
index ee7dd128f1..75505d7d84 100644
--- a/lib/stdlib/doc/src/unicode_usage.xml
+++ b/lib/stdlib/doc/src/unicode_usage.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>1999</year>
- <year>2013</year>
+ <year>2014</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -41,10 +41,10 @@
future.</p>
<p>The functionality described in EEP10 was implemented in Erlang/OTP
- as of R13A, but that was by no means the end of it. In R14B01 support
+ R13A, but that was by no means the end of it. In Erlang/OTP R14B01 support
for Unicode file names was added, although it was in no way complete
and was by default disabled on platforms where no guarantee was given
- for the file name encoding. With R16A came support for UTF-8 encoded
+ for the file name encoding. With Erlang/OTP R16A came support for UTF-8 encoded
source code, among with enhancements to many of the applications to
support both Unicode encoded file names as well as support for UTF-8
encoded files in several circumstances. Most notable is the support
@@ -52,8 +52,8 @@
for UTF-8 and more support for Unicode character sets in the
I/O-system.</p>
- <p>In 17.0, the encoding default for Erlang source files was
- switched to UTF-8 and in 18.0 Erlang will support atoms in the full
+ <p>In Erlang/OTP 17.0, the encoding default for Erlang source files was
+ switched to UTF-8 and in Erlang/OTP 18.0 Erlang will support atoms in the full
Unicode range, meaning full Unicode function and module
names</p>
@@ -222,7 +222,7 @@
<tag>Representation</tag>
<item>To handle Unicode characters in Erlang, we have to have a
common representation both in lists and binaries. The EEP (10) and
- the subsequent initial implementation in R13A settled a standard
+ the subsequent initial implementation in Erlang/OTP R13A settled a standard
representation of Unicode characters in Erlang.</item>
<tag>Manipulation</tag>
<item>The Unicode characters need to be processed by the Erlang
@@ -274,9 +274,9 @@
(<c>+fnu</c>) on platforms where this is not the default.</item>
<tag>Source code encoding</tag>
<item>When it comes to the Erlang source code, there is support
- for the UTF-8 encoding and bytewise encoding. The default in R16B
- is bytewise (or latin1) encoding. You can control the encoding by
- a comment like:
+ for the UTF-8 encoding and bytewise encoding. The default in
+ Erlang/OTP R16B was bytewise (or latin1) encoding; in Erlang/OTP 17.0
+ it was changed to UTF-8. You can control the encoding by a comment like:
<code>
%% -*- coding: utf-8 -*-
</code>
@@ -290,7 +290,7 @@
<item>Having the source code in UTF-8 also allows you to write
string literals containing Unicode characters with code points &gt;
255, although atoms, module names and function names will be
- restricted to the ISO-Latin-1 range until the 18.0 release. Binary
+ restricted to the ISO-Latin-1 range until the Erlang/OTP 18.0 release. Binary
literals where you use the <c>/utf8</c> type, can also be
expressed using Unicode characters &gt; 255. Having module names
using characters other than 7-bit ASCII can cause trouble on
@@ -304,7 +304,7 @@
<section>
<title>Standard Unicode Representation</title>
<p>In Erlang, strings are actually lists of integers. A string was
- up until R13 defined to be encoded in the ISO-latin-1 (ISO8859-1)
+ up until Erlang/OTP R13 defined to be encoded in the ISO-latin-1 (ISO8859-1)
character set, which is, code point by code point, a sub-range of
the Unicode character set.</p>
<p>The standard list encoding for strings was therefore easily
@@ -321,7 +321,7 @@
encoding has to be decided upon and the string should be converted
to a binary in the preferred encoding using
<c>unicode:characters_to_binary/{1,2,3}</c>. Strings are not
- generally lists of bytes, as they were before R13. They are lists of
+ generally lists of bytes, as they were before Erlang/OTP R13. They are lists of
characters. Characters are not generally bytes, they are Unicode
code points.</p>
@@ -447,8 +447,8 @@ Bin4 = &lt;&lt;"Hello"/utf16&gt;&gt;,</code>
probably will not appreciate). Another way is to keep it backwards
compatible so that only the ISO-Latin-1 character set is used to
detect a string. A third way would be to let the user decide
- exactly what Unicode ranges are to be viewed as characters. In
- R16B you can select either the whole Unicode range or the
+ exactly what Unicode ranges are to be viewed as characters. Since
+ Erlang/OTP R16B you can select either the whole Unicode range or the
ISO-Latin-1 range by supplying the startup flag <c>+pc
</c><i>Range</i>, where <i>Range</i> is either <c>latin1</c> or
<c>unicode</c>. For backwards compatibility, the default is
@@ -685,7 +685,7 @@ Eshell V5.10.1 (abort with ^G)
</item>
</taglist>
- <p>The Unicode file naming support was introduced with OTP release
+ <p>The Unicode file naming support was introduced with Erlang/OTP
R14B01. A VM operating in Unicode file name translation mode can
work with files having names in any language or character set (as
long as it is supported by the underlying OS and file system). The
@@ -709,7 +709,7 @@ Eshell V5.10.1 (abort with ^G)
problem even if it uses transparent file naming. Very few systems
have mixed file name encodings. A consistent UTF-8 named system will
work perfectly in Unicode file name mode. It was still however
- considered experimental in R14B01 and is still not the default on
+ considered experimental in Erlang/OTP R14B01 and is still not the default on
such systems. Unicode file name translation is turned on with the
<c>+fnu</c> switch to the On Linux, a VM started without explicitly
stating the file name translation mode will default to <c>latin1</c>
@@ -757,7 +757,7 @@ Eshell V5.10.1 (abort with ^G)
<title>Notes About Raw File Names</title>
<marker id="notes-about-raw-filenames"/>
<p>Raw file names were introduced together with Unicode file name
- support in erts-5.8.2 (OTP R14B01). The reason &quot;raw file
+ support in erts-5.8.2 (Erlang/OTP R14B01). The reason &quot;raw file
names&quot; was introduced in the system was to be able to
consistently represent file names given in different encodings on
the same system. Having the VM automatically translate a file name
@@ -798,10 +798,10 @@ Eshell V5.10.1 (abort with ^G)
the argument as a binary.</p>
<p>To force Unicode file name translation mode on systems where this
- is not the default was considered experimental in OTP R14B01 due to
+ is not the default was considered experimental in Erlang/OTP R14B01 due to
the fact that the initial implementation did not ignore wrongly
encoded file names, so that raw file names could spread unexpectedly
- throughout the system. Beginning with R16B, the wrongly encoded file
+ throughout the system. Beginning with Erlang/OTP R16B, the wrongly encoded file
names are only retrieved by special functions
(e.g. <c>file:list_dir_all/1</c>), so the impact on existing code is
much lower, why it is now supported. Unicode file name translation
@@ -1032,7 +1032,7 @@ ok
<c>io</c>/<c>io_lib:format</c> with the <c>"~tp"</c> and
<c>~tP</c> formatting instructions, as described above.</p>
<p>You can check this option by calling io:printable_range/0,
- which in R16B will return <c>unicode</c> or <c>latin1</c>. To be
+ which will return <c>unicode</c> or <c>latin1</c>. To be
compatible with future (expected) extensions to the settings,
one should rather use <c>io_lib:printable_list/1</c> to check if
a list is printable according to the setting. That function will
@@ -1070,8 +1070,8 @@ ok
<item>
<p>This function returns the default encoding for Erlang source
files (if no encoding comment is present) in the currently
- running release. For R16 this returns <c>latin1</c> (meaning
- bytewise encoding). In 17.0 and forward it returns
+ running release. In Erlang/OTP R16B <c>latin1</c> was returned (meaning
+ bytewise encoding). In Erlang/OTP 17.0 and forward it returns
<c>utf8</c>.</p>
<p>The encoding of each file can be specified using comments as
described in
diff --git a/lib/stdlib/src/edlin_expand.erl b/lib/stdlib/src/edlin_expand.erl
index 516c0aa30b..0033010dce 100644
--- a/lib/stdlib/src/edlin_expand.erl
+++ b/lib/stdlib/src/edlin_expand.erl
@@ -89,7 +89,13 @@ match(Prefix, Alts, Extra) ->
{yes, Remain, []}
end;
{complete, Str} ->
- {yes, nthtail(Len, Str) ++ Extra, []};
+ {_, Arity} = lists:keyfind(Str, 1, Matches),
+ case {Arity, Extra} of
+ {0, "("} ->
+ {yes, nthtail(Len, Str) ++ "()", []};
+ _ ->
+ {yes, nthtail(Len, Str) ++ Extra, []}
+ end;
no ->
{no, [], []}
end.
diff --git a/lib/stdlib/src/erl_lint.erl b/lib/stdlib/src/erl_lint.erl
index f630db6032..0c6f41f594 100644
--- a/lib/stdlib/src/erl_lint.erl
+++ b/lib/stdlib/src/erl_lint.erl
@@ -100,7 +100,7 @@ value_option(Flag, Default, On, OnVal, Off, OffVal, Opts) ->
compile=[], %Compile flags
records=dict:new() :: dict(), %Record definitions
locals=gb_sets:empty() :: gb_set(), %All defined functions (prescanned)
- no_auto=gb_sets:empty() :: gb_set(), %Functions explicitly not autoimported
+ no_auto=gb_sets:empty() :: gb_set() | 'all', %Functions explicitly not autoimported
defined=gb_sets:empty() :: gb_set(), %Defined fuctions
on_load=[] :: [fa()], %On-load function
on_load_line=0 :: line(), %Line for on_load
@@ -3648,15 +3648,22 @@ is_imported_from_erlang(ImportSet,{Func,Arity}) ->
{ok,erlang} -> true;
_ -> false
end.
-%% Build set of functions where auto-import is explicitly supressed
+%% Build set of functions where auto-import is explicitly suppressed
auto_import_suppressed(CompileFlags) ->
- L0 = [ X || {no_auto_import,X} <- CompileFlags ],
- L1 = [ {Y,Z} || {Y,Z} <- lists:flatten(L0), is_atom(Y), is_integer(Z) ],
- gb_sets:from_list(L1).
-%% Predicate to find out if autoimport is explicitly supressed for a function
+ case lists:member(no_auto_import, CompileFlags) of
+ true ->
+ all;
+ false ->
+ L0 = [ X || {no_auto_import,X} <- CompileFlags ],
+ L1 = [ {Y,Z} || {Y,Z} <- lists:flatten(L0), is_atom(Y), is_integer(Z) ],
+ gb_sets:from_list(L1)
+ end.
+%% Predicate to find out if autoimport is explicitly suppressed for a function
+is_autoimport_suppressed(all,{_Func,_Arity}) ->
+ true;
is_autoimport_suppressed(NoAutoSet,{Func,Arity}) ->
gb_sets:is_element({Func,Arity},NoAutoSet).
-%% Predicate to find out if a function specific bif-clash supression (old deprecated) is present
+%% Predicate to find out if a function specific bif-clash suppression (old deprecated) is present
bif_clash_specifically_disabled(St,{F,A}) ->
Nowarn = nowarn_function(nowarn_bif_clash, St#lint.compile),
lists:member({F,A},Nowarn).
diff --git a/lib/stdlib/src/lists.erl b/lib/stdlib/src/lists.erl
index d6a9f4645d..6303465d3d 100644
--- a/lib/stdlib/src/lists.erl
+++ b/lib/stdlib/src/lists.erl
@@ -22,7 +22,7 @@
-compile({no_auto_import,[min/2]}).
-export([append/2, append/1, subtract/2, reverse/1,
- nth/2, nthtail/2, prefix/2, suffix/2, last/1,
+ nth/2, nthtail/2, prefix/2, suffix/2, droplast/1, last/1,
seq/2, seq/3, sum/1, duplicate/2, min/1, max/1, sublist/2, sublist/3,
delete/2,
unzip/1, unzip3/1, zip/2, zip3/3, zipwith/3, zipwith3/4,
@@ -203,6 +203,19 @@ suffix(Suffix, List) ->
Delta = length(List) - length(Suffix),
Delta >= 0 andalso nthtail(Delta, List) =:= Suffix.
+%% droplast(List) returns the list dropping its last element
+
+-spec droplast(List) -> InitList when
+ List :: [T, ...],
+ InitList :: [T],
+ T :: term().
+
+%% This is the simple recursive implementation
+%% reverse(tl(reverse(L))) is faster on average,
+%% but creates more garbage.
+droplast([_T]) -> [];
+droplast([H|T]) -> [H|droplast(T)].
+
%% last(List) returns the last element in a list.
-spec last(List) -> Last when
diff --git a/lib/stdlib/test/edlin_expand_SUITE.erl b/lib/stdlib/test/edlin_expand_SUITE.erl
index 0cd2688e2e..2c1c5acf5a 100644
--- a/lib/stdlib/test/edlin_expand_SUITE.erl
+++ b/lib/stdlib/test/edlin_expand_SUITE.erl
@@ -76,11 +76,14 @@ normal(Config) when is_list(Config) ->
[{"a_fun_name",1},
{"a_less_fun_name",1},
{"b_comes_after_a",1},
+ {"expand0arity_entirely",0},
{"module_info",0},
{"module_info",1}]} = edlin_expand:expand(lists:reverse("expand_test:")),
?line {yes,[],[{"a_fun_name",1},
{"a_less_fun_name",1}]} = edlin_expand:expand(
lists:reverse("expand_test:a_")),
+ ?line {yes,"arity_entirely()",[]} = edlin_expand:expand(
+ lists:reverse("expand_test:expand0")),
ok.
quoted_fun(doc) ->
@@ -93,7 +96,7 @@ quoted_fun(Config) when is_list(Config) ->
%% should be no colon after test this time
?line {yes, "test", []} = edlin_expand:expand(lists:reverse("expand_")),
?line {no, [], []} = edlin_expand:expand(lists:reverse("expandXX_")),
- ?line {no,[],[{"'#weird-fun-name'",0},
+ ?line {no,[],[{"'#weird-fun-name'",1},
{"'Quoted_fun_name'",0},
{"'Quoted_fun_too'",0},
{"a_fun_name",1},
@@ -108,7 +111,7 @@ quoted_fun(Config) when is_list(Config) ->
{"a_less_fun_name",1}]} = edlin_expand:expand(
lists:reverse("expand_test1:a_")),
?line {yes,[],
- [{"'#weird-fun-name'",0},
+ [{"'#weird-fun-name'",1},
{"'Quoted_fun_name'",0},
{"'Quoted_fun_too'",0}]} = edlin_expand:expand(
lists:reverse("expand_test1:'")),
@@ -172,6 +175,6 @@ quoted_both(Config) when is_list(Config) ->
[{"'Quoted_fun_name'",0},
{"'Quoted_fun_too'",0}]} = edlin_expand:expand(
lists:reverse("'ExpandTestCaps1':'Quoted_fun_")),
- ?line {yes,"weird-fun-name'(",[]} = edlin_expand:expand(
- lists:reverse("'ExpandTestCaps1':'#")),
+ ?line {yes,"weird-fun-name'()",[]} = edlin_expand:expand(
+ lists:reverse("'ExpandTestCaps1':'#")),
ok.
diff --git a/lib/stdlib/test/erl_lint_SUITE.erl b/lib/stdlib/test/erl_lint_SUITE.erl
index 6e9a9dd7bf..48f50d5f43 100644
--- a/lib/stdlib/test/erl_lint_SUITE.erl
+++ b/lib/stdlib/test/erl_lint_SUITE.erl
@@ -2827,7 +2827,24 @@ bif_clash(Config) when is_list(Config) ->
{6,erl_lint,{illegal_guard_local_call,{is_tuple,1}}},
{7,erl_lint,{illegal_guard_local_call,{is_list,1}}},
{8,erl_lint,{illegal_guard_local_call,{is_record,3}}},
- {9,erl_lint,{illegal_guard_local_call,{is_record,3}}}],[]}}
+ {9,erl_lint,{illegal_guard_local_call,{is_record,3}}}],[]}},
+ %% We can also suppress all auto imports at once
+ {clash22,
+ <<"-export([size/1, binary_part/2]).
+ -compile(no_auto_import).
+ size([]) ->
+ 0;
+ size({N,_}) ->
+ N;
+ size([_|T]) ->
+ 1+size(T).
+ binary_part({B,_},{X,Y}) ->
+ binary_part(B,{X,Y});
+ binary_part(B,{X,Y}) ->
+ binary:part(B,X,Y).
+ ">>,
+ [],
+ []}
],
?line [] = run(Config, Ts),
diff --git a/lib/stdlib/test/expand_test.erl b/lib/stdlib/test/expand_test.erl
index 63e4bc3aa0..b9db32c352 100644
--- a/lib/stdlib/test/expand_test.erl
+++ b/lib/stdlib/test/expand_test.erl
@@ -20,7 +20,8 @@
-export([a_fun_name/1,
a_less_fun_name/1,
- b_comes_after_a/1]).
+ b_comes_after_a/1,
+ expand0arity_entirely/0]).
a_fun_name(X) ->
X.
@@ -30,3 +31,6 @@ a_less_fun_name(X) ->
b_comes_after_a(X) ->
X.
+
+expand0arity_entirely () ->
+ ok.
diff --git a/lib/stdlib/test/expand_test1.erl b/lib/stdlib/test/expand_test1.erl
index 11b6fec0f3..1d375e5677 100644
--- a/lib/stdlib/test/expand_test1.erl
+++ b/lib/stdlib/test/expand_test1.erl
@@ -23,7 +23,7 @@
b_comes_after_a/1,
'Quoted_fun_name'/0,
'Quoted_fun_too'/0,
- '#weird-fun-name'/0]).
+ '#weird-fun-name'/1]).
a_fun_name(X) ->
X.
@@ -40,5 +40,5 @@ b_comes_after_a(X) ->
'Quoted_fun_too'() ->
too.
-'#weird-fun-name'() ->
+'#weird-fun-name'(_) ->
weird.
diff --git a/lib/stdlib/test/lists_SUITE.erl b/lib/stdlib/test/lists_SUITE.erl
index 92253ef5b9..f4589a8e24 100644
--- a/lib/stdlib/test/lists_SUITE.erl
+++ b/lib/stdlib/test/lists_SUITE.erl
@@ -61,7 +61,7 @@
zip_unzip/1, zip_unzip3/1, zipwith/1, zipwith3/1,
filter_partition/1,
otp_5939/1, otp_6023/1, otp_6606/1, otp_7230/1,
- suffix/1, subtract/1]).
+ suffix/1, subtract/1, droplast/1]).
%% Sort randomized lists until stopped.
%%
@@ -2641,4 +2641,12 @@ sub_non_matching(A, B) ->
sub(A, B) ->
Res = A -- B,
Res = lists:subtract(A, B).
-
+
+%% Test lists:droplast/1
+droplast(Config) when is_list(Config) ->
+ ?line [] = lists:droplast([x]),
+ ?line [x] = lists:droplast([x, y]),
+ ?line {'EXIT', {function_clause, _}} = (catch lists:droplast([])),
+ ?line {'EXIT', {function_clause, _}} = (catch lists:droplast(x)),
+
+ ok.