diff options
Diffstat (limited to 'lib/stdlib')
29 files changed, 2100 insertions, 1377 deletions
diff --git a/lib/stdlib/doc/src/Makefile b/lib/stdlib/doc/src/Makefile index 16e0a86e3b..6c92756ae7 100644 --- a/lib/stdlib/doc/src/Makefile +++ b/lib/stdlib/doc/src/Makefile @@ -83,7 +83,6 @@ XML_REF3_FILES = \ queue.xml \ random.xml \ re.xml \ - regexp.xml \ sets.xml \ shell.xml \ shell_default.xml \ diff --git a/lib/stdlib/doc/src/filename.xml b/lib/stdlib/doc/src/filename.xml index bc3a616d39..9296319b83 100644 --- a/lib/stdlib/doc/src/filename.xml +++ b/lib/stdlib/doc/src/filename.xml @@ -295,6 +295,12 @@ <p>Finds the source filename and compiler options for a module. The result can be fed to <c>compile:file/2</c> in order to compile the file again.</p> + + <warning><p>We don't recommend using this function. If possible, + use <seealso marker="beam_lib">beam_lib(3)</seealso> to extract + the abstract code format from the BEAM file and compile that + instead.</p></warning> + <p>The <c><anno>Beam</anno></c> argument, which can be a string or an atom, specifies either the module name or the path to the source code, with or without the <c>".erl"</c> extension. In either diff --git a/lib/stdlib/doc/src/gen_event.xml b/lib/stdlib/doc/src/gen_event.xml index 24bcb419fe..79a0c8ad89 100644 --- a/lib/stdlib/doc/src/gen_event.xml +++ b/lib/stdlib/doc/src/gen_event.xml @@ -195,12 +195,13 @@ gen_event:stop -----> Module:terminate/2 handlers using the same callback module.</p> <p><c>Args</c> is an arbitrary term which is passed as the argument to <c>Module:init/1</c>.</p> - <p>If <c>Module:init/1</c> returns a correct value, the event - manager adds the event handler and this function returns + <p>If <c>Module:init/1</c> returns a correct value indicating + successful completion, the event manager adds the event + handler and this function returns <c>ok</c>. If <c>Module:init/1</c> fails with <c>Reason</c> or - returns an unexpected value <c>Term</c>, the event handler is + returns <c>{error,Reason}</c>, the event handler is ignored and this function returns <c>{'EXIT',Reason}</c> or - <c>Term</c>, respectively.</p> + <c>{error,Reason}</c>, respectively.</p> </desc> </func> <func> @@ -448,12 +449,13 @@ gen_event:stop -----> Module:terminate/2 </section> <funcs> <func> - <name>Module:init(InitArgs) -> {ok,State} | {ok,State,hibernate}</name> + <name>Module:init(InitArgs) -> {ok,State} | {ok,State,hibernate} | {error,Reason}</name> <fsummary>Initialize an event handler.</fsummary> <type> <v>InitArgs = Args | {Args,Term}</v> <v> Args = Term = term()</v> <v>State = term()</v> + <v>Reason = term()</v> </type> <desc> <p>Whenever a new event handler is added to an event manager, @@ -470,8 +472,9 @@ gen_event:stop -----> Module:terminate/2 the argument provided in the function call/return tuple and <c>Term</c> is the result of terminating the old event handler, see <c>gen_event:swap_handler/3</c>.</p> - <p>The function should return <c>{ok,State}</c> or <c>{ok,State, hibernate}</c> - where <c>State</c> is the initial internal state of the event handler.</p> + <p>If successful, the function should return <c>{ok,State}</c> + or <c>{ok,State,hibernate}</c> where <c>State</c> is the + initial internal state of the event handler.</p> <p>If <c>{ok,State,hibernate}</c> is returned, the event manager will go into hibernation (by calling <seealso marker="proc_lib#hibernate/3">proc_lib:hibernate/3</seealso>), diff --git a/lib/stdlib/doc/src/gen_server.xml b/lib/stdlib/doc/src/gen_server.xml index 1045766e01..edeb7dff91 100644 --- a/lib/stdlib/doc/src/gen_server.xml +++ b/lib/stdlib/doc/src/gen_server.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>1996</year><year>2010</year> + <year>1996</year><year>2011</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -570,13 +570,14 @@ gen_server:abcast -----> Module:handle_cast/2 </desc> </func> <func> - <name>Module:code_change(OldVsn, State, Extra) -> {ok, NewState}</name> + <name>Module:code_change(OldVsn, State, Extra) -> {ok, NewState} | {error, Reason}</name> <fsummary>Update the internal state during upgrade/downgrade.</fsummary> <type> <v>OldVsn = Vsn | {down, Vsn}</v> <v> Vsn = term()</v> <v>State = NewState = term()</v> <v>Extra = term()</v> + <v>Reason = term()</v> </type> <desc> <p>This function is called by a gen_server when it should @@ -595,7 +596,10 @@ gen_server:abcast -----> Module:handle_cast/2 <p><c>State</c> is the internal state of the gen_server.</p> <p><c>Extra</c> is passed as-is from the <c>{advanced,Extra}</c> part of the update instruction.</p> - <p>The function should return the updated internal state.</p> + <p>If successful, the function shall return the updated + internal state.</p> + <p>If the function returns <c>{error,Reason}</c>, the ongoing + upgrade will fail and roll back to the old release.</p> </desc> </func> <func> diff --git a/lib/stdlib/doc/src/io_protocol.xml b/lib/stdlib/doc/src/io_protocol.xml index 3e8ab1affc..0ff3d5c1ee 100644 --- a/lib/stdlib/doc/src/io_protocol.xml +++ b/lib/stdlib/doc/src/io_protocol.xml @@ -50,10 +50,10 @@ current I/O-protocol.</p> and execution time efficiency has triggered extensions to the protocol over the years, making the protocol larger and somewhat less easy to implement than the original. It can certainly be argumented that the -current protocol is to complex, but this text describes how it looks +current protocol is too complex, but this text describes how it looks today, not how it should have looked.</p> -<p>The basic ideas from the original protocol still holds. The io_server +<p>The basic ideas from the original protocol still hold. The io_server and client communicate with one single, rather simplistic protocol and no server state is ever present in the client. Any io_server can be used together with any client code and client code need not be aware @@ -62,7 +62,7 @@ of the actual device the io_server communicates with.</p> <section> <title>Protocol basics</title> -<p>As described in Roberts paper, servers and clients communicate using +<p>As described in Robert's paper, servers and clients communicate using io_request/io_reply tuples as follows:</p> <p><em>{io_request, From, ReplyAs, Request}</em><br/> @@ -103,7 +103,7 @@ Reply part.</p> <em>{put_chars, Encoding, Module, Function, Args}</em> </p> <list type="bulleted"> -<item>Encoding is either 'latin1' or 'unicode', meaning that the +<item>Encoding is either 'unicode' or 'latin1', meaning that the characters are (in case of binaries) encoded as either UTF-8 or iso-latin-1 (pure bytes). A well behaved io_server should also return error if list elements contain integers > 255 when the @@ -116,13 +116,13 @@ Reply part.</p> produces. Note that byte-oriented data is simplest sent using latin1 Encoding</item> -<item>Characters are the data to be put on the device. If encoding is - latin1, this is an iolist(). If encoding is unicode, this is an +<item>Characters are the data to be put on the device. If Encoding is + latin1, this is an iolist(). If Encoding is unicode, this is an Erlang standard mixed unicode list (one integer in a list per character, characters in binaries represented as UTF-8).</item> <item>Module, Function, Args denotes a function which will be called to - produce the data (like io_lib:format), Args is a list of arguments + produce the data (like io_lib:format). Args is a list of arguments to the function. The function should produce data in the given Encoding. The io_server should call the function as apply(Mod, Func, Args) and will put the returned data on the device as if it was sent @@ -164,7 +164,7 @@ latin1, Module, Function, Args} respectively. </p> <list type="bulleted"> <item>Encoding denotes how data is to be sent back to the client and what data is sent to the function denoted by - Module/Function/Arity. If the function supplied returns data as a + Module/Function/ExtraArgs. If the function supplied returns data as a list, the data is converted to this encoding. If however the function supplied returns data in some other format, no conversion can be done and it's up to the client supplied function to return @@ -179,7 +179,7 @@ latin1, Module, Function, Args} respectively. </p> <item>Prompt is a list of characters (not mixed, no binaries) or an atom() to be output as a prompt for input on the device. The Prompt is often ignored by the io_server and a Prompt set to '' should always - be ignored (and result in nothing being written to the device). </item> + be ignored (and result in nothing being written to the device).</item> <item><p>Module, Function, ExtraArgs denotes a function and arguments to determine when enough data is written. The function should take two @@ -550,7 +550,7 @@ request({get_line, Encoding, _Prompt}, State) -> </code> <p>Here we have cheated a little by more or less only implementing -get_until and using internal helpers to implement get__chars and +get_until and using internal helpers to implement get_chars and get_line. In production code, this might be to inefficient, but that of course depends on the frequency of the different requests. Before we start actually implementing the functions put_chars/2 and @@ -618,7 +618,7 @@ encounter an error or the list is exhausted. The last return value is sent back to the client (it's first returned to the main loop and then sent back by the function io_reply).</p> -<p>The getopt and setopt requests is also simple to handle, we just +<p>The getopt and setopt requests are also simple to handle, we just change or read our state record:</p> <code> diff --git a/lib/stdlib/doc/src/re.xml b/lib/stdlib/doc/src/re.xml index 18867cfb68..6d5336796c 100644 --- a/lib/stdlib/doc/src/re.xml +++ b/lib/stdlib/doc/src/re.xml @@ -41,8 +41,7 @@ strings and binaries.</p> <p>The regular expression syntax and semantics resemble that of - Perl. This library replaces the deprecated pure-Erlang regexp - library; it has a richer syntax, more options and is faster.</p> + Perl.</p> <p>The library's matching algorithms are currently based on the PCRE library, but not all of the PCRE library is interfaced and diff --git a/lib/stdlib/doc/src/ref_man.xml b/lib/stdlib/doc/src/ref_man.xml index 85aae6151d..6373922c92 100644 --- a/lib/stdlib/doc/src/ref_man.xml +++ b/lib/stdlib/doc/src/ref_man.xml @@ -80,7 +80,6 @@ <xi:include href="queue.xml"/> <xi:include href="random.xml"/> <xi:include href="re.xml"/> - <xi:include href="regexp.xml"/> <xi:include href="sets.xml"/> <xi:include href="shell.xml"/> <xi:include href="shell_default.xml"/> diff --git a/lib/stdlib/doc/src/regexp.xml b/lib/stdlib/doc/src/regexp.xml deleted file mode 100644 index 35d8e1c3f8..0000000000 --- a/lib/stdlib/doc/src/regexp.xml +++ /dev/null @@ -1,381 +0,0 @@ -<?xml version="1.0" encoding="latin1" ?> -<!DOCTYPE erlref SYSTEM "erlref.dtd"> - -<erlref> - <header> - <copyright> - <year>1996</year><year>2011</year> - <holder>Ericsson AB. All Rights Reserved.</holder> - </copyright> - <legalnotice> - The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved online at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - the License for the specific language governing rights and limitations - under the License. - - </legalnotice> - - <title>regexp</title> - <prepared>Robert Virding</prepared> - <responsible>Bjarne Dacker</responsible> - <docno>1</docno> - <approved>Bjarne Däcker</approved> - <checked></checked> - <date>96-09-28</date> - <rev>A</rev> - <file>regexp.sgml</file> - </header> - <module>regexp</module> - <modulesummary>Regular Expression Functions for Strings</modulesummary> - <description> - <note><p>This module has been obsoleted by the - <seealso marker="re">re</seealso> module and will be removed in a future - release.</p></note> - <p>This module contains functions for regular expression - matching and substitution.</p> - </description> - <datatypes> - <datatype> - <name name="errordesc"></name> - </datatype> - <datatype> - <name name="regexp"></name> - <desc><p>Internal representation of a regular expression.</p></desc> - </datatype> - </datatypes> - <funcs> - <func> - <name name="match" arity="2"/> - <fsummary>Match a regular expression</fsummary> - <desc> - <p>Finds the first, longest match of the regular expression <c><anno>RegExp</anno></c> in <c><anno>String</anno></c>. This function searches for the longest possible match and returns the first one found if there are several expressions of the same length. It returns as follows:</p> - <taglist> - <tag><c>{match,<anno>Start</anno>,<anno>Length</anno>}</c></tag> - <item> - <p>if the match succeeded. <c><anno>Start</anno></c> is the starting - position of the match, and <c><anno>Length</anno></c> is the length of - the matching string.</p> - </item> - <tag><c>nomatch</c></tag> - <item> - <p>if there were no matching characters.</p> - </item> - <tag><c>{error,<anno>Error</anno>}</c></tag> - <item> - <p>if there was an error in <c><anno>RegExp</anno></c>.</p> - </item> - </taglist> - </desc> - </func> - <func> - <name name="first_match" arity="2"/> - <fsummary>Match a regular expression</fsummary> - <desc> - <p>Finds the first match of the regular expression <c><anno>RegExp</anno></c> in <c><anno>String</anno></c>. This call is - usually faster than <c>match</c> and it is also a useful way to ascertain that a match exists. It returns as follows:</p> - <taglist> - <tag><c>{match,<anno>Start</anno>,<anno>Length</anno>}</c></tag> - <item> - <p>if the match succeeded. <c><anno>Start</anno></c> is the starting - position of the match and <c><anno>Length</anno></c> is the length of - the matching string.</p> - </item> - <tag><c>nomatch</c></tag> - <item> - <p>if there were no matching characters.</p> - </item> - <tag><c>{error,<anno>Error</anno>}</c></tag> - <item> - <p>if there was an error in <c><anno>RegExp</anno></c>.</p> - </item> - </taglist> - </desc> - </func> - <func> - <name name="matches" arity="2"/> - <fsummary>Match a regular expression</fsummary> - <desc> - <p>Finds all non-overlapping matches of the - expression <c><anno>RegExp</anno></c> in <c><anno>String</anno></c>. - It returns as follows:</p> - <taglist> - <tag><c>{match, <anno>Matches</anno>}</c></tag> - <item> - <p>if the regular expression was correct. - The list will be empty if there was no match. Each element in the list looks like <c>{<anno>Start</anno>, <anno>Length</anno>}</c>, where <c><anno>Start</anno></c> is the starting position of the match, and <c><anno>Length</anno></c> is the length of the matching string.</p> - </item> - <tag><c>{error,<anno>Error</anno>}</c></tag> - <item> - <p>if there was an error in <c><anno>RegExp</anno></c>.</p> - </item> - </taglist> - </desc> - </func> - <func> - <name name="sub" arity="3"/> - <fsummary>Substitute the first occurrence of a regular expression</fsummary> - <desc> - <p>Substitutes the first occurrence of a substring matching <c><anno>RegExp</anno></c> in <c><anno>String</anno></c> with the string <c><anno>New</anno></c>. A <c><![CDATA[&]]></c> in the string <c><anno>New</anno></c> is replaced by the matched substring of <c><anno>String</anno></c>. <c><![CDATA[\&]]></c> puts a literal <c><![CDATA[&]]></c> into the replacement string. It returns as follows:</p> - <taglist> - <tag><c>{ok,<anno>NewString</anno>,<anno>RepCount</anno>}</c></tag> - <item> - <p>if <c><anno>RegExp</anno></c> is correct. <c><anno>RepCount</anno></c> is the number of replacements which have been made - (this will be either 0 or 1).</p> - </item> - <tag><c>{error, <anno>Error</anno>}</c></tag> - <item> - <p>if there is an error in <c><anno>RegExp</anno></c>.</p> - </item> - </taglist> - </desc> - </func> - <func> - <name name="gsub" arity="3"/> - <fsummary>Substitute all occurrences of a regular expression</fsummary> - <desc> - <p>The same as <c>sub</c>, except that all non-overlapping - occurrences of a substring matching - <c><anno>RegExp</anno></c> in <c><anno>String</anno></c> are replaced by the string <c><anno>New</anno></c>. It returns:</p> - <taglist> - <tag><c>{ok,<anno>NewString</anno>,<anno>RepCount</anno>}</c></tag> - <item> - <p>if <c><anno>RegExp</anno></c> is correct. <c><anno>RepCount</anno></c> is the number of replacements which have been made.</p> - </item> - <tag><c>{error, <anno>Error</anno>}</c></tag> - <item> - <p>if there is an error in <c><anno>RegExp</anno></c>.</p> - </item> - </taglist> - </desc> - </func> - <func> - <name name="split" arity="2"/> - <fsummary>Split a string into fields</fsummary> - <desc> - <p><c><anno>String</anno></c> is split into fields (sub-strings) by the - regular expression <c><anno>RegExp</anno></c>.</p> - <p>If the separator expression is <c>" "</c> (a single space), - then the fields are separated by blanks and/or tabs and - leading and trailing blanks and tabs are discarded. For all - other values of the separator, leading and trailing blanks - and tabs are not discarded. It returns:</p> - <taglist> - <tag><c>{ok, <anno>FieldList</anno>}</c></tag> - <item> - <p>to indicate that the string has been split up into the fields of - <c><anno>FieldList</anno></c>.</p> - </item> - <tag><c>{error, <anno>Error</anno>}</c></tag> - <item> - <p>if there is an error in <c><anno>RegExp</anno></c>.</p> - </item> - </taglist> - </desc> - </func> - <func> - <name name="sh_to_awk" arity="1"/> - <fsummary>Convert an <c>sh</c>regular expression into an <c>AWK</c>one</fsummary> - <desc> - <p>Converts the <c>sh</c> type regular expression - <c><anno>ShRegExp</anno></c> into a full <c>AWK</c> regular - expression. Returns the converted regular expression - string. <c>sh</c> expressions are used in the shell for - matching file names and have the following special - characters:</p> - <taglist> - <tag><c>*</c></tag> - <item> - <p>matches any string including the null string.</p> - </item> - <tag><c>?</c></tag> - <item> - <p>matches any single character.</p> - </item> - <tag><c>[...]</c></tag> - <item> - <p>matches any of the enclosed characters. Character - ranges are specified by a pair of characters separated - by a <c>-</c>. If the first character after <c>[</c> is a - <c>!</c>, then any character not enclosed is matched.</p> - </item> - </taglist> - <p>It may sometimes be more practical to use <c>sh</c> type - expansions as they are simpler and easier to use, even though they are not as powerful.</p> - </desc> - </func> - <func> - <name name="parse" arity="1"/> - <fsummary>Parse a regular expression</fsummary> - <desc> - <p>Parses the regular expression <c><anno>RegExp</anno></c> and builds the - internal representation used in the other regular expression - functions. Such representations can be used in all of the - other functions instead of a regular expression string. This - is more efficient when the same regular expression is used - in many strings. It returns:</p> - <taglist> - <tag><c>{ok, <anno>RE</anno>}</c></tag> - <item> - <p>if <c>RegExp</c> is correct and <c><anno>RE</anno></c> is the internal representation.</p> - </item> - <tag><c>{error, <anno>Error</anno>}</c></tag> - <item> - <p>if there is an error in <c><anno>RegExp</anno></c>.</p> - </item> - </taglist> - </desc> - </func> - <func> - <name name="format_error" arity="1"/> - <fsummary>Format an error descriptor</fsummary> - <desc> - <p>Returns a string which describes the error <c><anno>ErrorDescriptor</anno></c> - returned when there is an error in a regular expression.</p> - </desc> - </func> - </funcs> - - <section> - <title>Regular Expressions</title> - <p>The regular expressions allowed here is a subset of the set found - in <c>egrep</c> and in the <c>AWK</c> programming language, as - defined in the book, <c>The AWK Programming Language, by A. V. Aho, B. W. Kernighan, P. J. Weinberger</c>. They are - composed of the following characters:</p> - <taglist> - <tag>c</tag> - <item> - <p>matches the non-metacharacter <c>c</c>.</p> - </item> - <tag>\c</tag> - <item> - <p>matches the escape sequence or literal character <c>c</c>.</p> - </item> - <tag>.</tag> - <item> - <p>matches any character.</p> - </item> - <tag>^</tag> - <item> - <p>matches the beginning of a string.</p> - </item> - <tag>$</tag> - <item> - <p>matches the end of a string.</p> - </item> - <tag>[abc...]</tag> - <item> - <p>character class, which matches any of the characters - <c>abc...</c> Character ranges are specified by a pair of - characters separated by a <c>-</c>.</p> - </item> - <tag>[^abc...]</tag> - <item> - <p>negated character class, which matches any character except - <c>abc...</c>.</p> - </item> - <tag>r1 | r2</tag> - <item> - <p>alternation. It matches either <c>r1</c> or <c>r2</c>.</p> - </item> - <tag>r1r2</tag> - <item> - <p>concatenation. It matches <c>r1</c> and then <c>r2</c>.</p> - </item> - <tag>r+</tag> - <item> - <p>matches one or more <c>r</c>s.</p> - </item> - <tag>r*</tag> - <item> - <p>matches zero or more <c>r</c>s.</p> - </item> - <tag>r?</tag> - <item> - <p>matches zero or one <c>r</c>s.</p> - </item> - <tag>(r)</tag> - <item> - <p>grouping. It matches <c>r</c>.</p> - </item> - </taglist> - <p>The escape sequences allowed are the same as for Erlang - strings:</p> - <taglist> - <tag><c>\b</c></tag> - <item> - <p>backspace</p> - </item> - <tag><c>\f</c></tag> - <item> - <p>form feed </p> - </item> - <tag><c>\n</c></tag> - <item> - <p>newline (line feed) </p> - </item> - <tag><c>\r</c></tag> - <item> - <p>carriage return </p> - </item> - <tag><c>\t</c></tag> - <item> - <p>tab </p> - </item> - <tag><c>\e</c></tag> - <item> - <p>escape </p> - </item> - <tag><c>\v</c></tag> - <item> - <p>vertical tab </p> - </item> - <tag><c>\s</c></tag> - <item> - <p>space </p> - </item> - <tag><c>\d</c></tag> - <item> - <p>delete </p> - </item> - <tag><c>\ddd</c></tag> - <item> - <p>the octal value ddd </p> - </item> - <tag><c>\xhh</c></tag> - <item> - <p>The hexadecimal value <c>hh</c>.</p> - </item> - <tag><c>\x{h...}</c></tag> - <item> - <p>The hexadecimal value <c>h...</c>.</p> - </item> - <tag><c>\c</c></tag> - <item> - <p>any other character literally, for example <c>\\</c> for backslash, - <c>\"</c> for ")</p> - </item> - </taglist> - <p>To make these functions easier to use, in combination with the - function <c>io:get_line</c> which terminates the input line with - a new line, the <c>$</c> characters also matches a string ending - with <c>"...\n"</c>. The following examples - define Erlang data types:</p> - <pre> -Atoms [a-z][0-9a-zA-Z_]* - -Variables [A-Z_][0-9a-zA-Z_]* - -Floats (\+|-)?[0-9]+\.[0-9]+((E|e)(\+|-)?[0-9]+)?</pre> - <p>Regular expressions are written as Erlang strings when used with the functions in this module. This means that any <c>\</c> or <c>"</c> characters in a regular expression - string must be written with <c>\</c> as they are also escape characters for the string. For example, the regular expression string for Erlang floats is: - <c>"(\\+|-)?[0-9]+\\.[0-9]+((E|e)(\\+|-)?[0-9]+)?"</c>.</p> - <p>It is not really necessary to have the escape sequences as part of the regular expression syntax as they can always be generated directly in the string. They are included for completeness and can they can also be useful when generating regular expressions, or when they are entered other than with Erlang strings.</p> - </section> -</erlref> - diff --git a/lib/stdlib/doc/src/specs.xml b/lib/stdlib/doc/src/specs.xml index 98338b5ec2..49c60529d2 100644 --- a/lib/stdlib/doc/src/specs.xml +++ b/lib/stdlib/doc/src/specs.xml @@ -46,7 +46,6 @@ <xi:include href="../specs/specs_queue.xml"/> <xi:include href="../specs/specs_random.xml"/> <xi:include href="../specs/specs_re.xml"/> - <xi:include href="../specs/specs_regexp.xml"/> <xi:include href="../specs/specs_sets.xml"/> <xi:include href="../specs/specs_shell.xml"/> <xi:include href="../specs/specs_shell_default.xml"/> diff --git a/lib/stdlib/doc/src/unicode_usage.xml b/lib/stdlib/doc/src/unicode_usage.xml index 0fa7de0a5c..a7e010a05f 100644 --- a/lib/stdlib/doc/src/unicode_usage.xml +++ b/lib/stdlib/doc/src/unicode_usage.xml @@ -59,7 +59,7 @@ <title>Standard Unicode representation in Erlang</title> <p>In Erlang, strings are actually lists of integers. A string is defined to be encoded in the ISO-latin-1 (ISO8859-1) character set, which is, codepoint by codepoint, a sub-range of the Unicode character set.</p> <p>The standard list encoding for strings is therefore easily extendible to cope with the whole Unicode range: A Unicode string in Erlang is simply a list containing integers, each integer being a valid Unicode codepoint and representing one character in the Unicode character set.</p> -<p>Regular Erlang strings in ISO-latin-1 are a subset of there Unicode strings.</p> +<p>Regular Erlang strings in ISO-latin-1 are a subset of their Unicode strings.</p> <p>Binaries on the other hand are more troublesome. For performance reasons, programs often store textual data in binaries instead of lists, mainly because they are more compact (one byte per character instead of two words per character, as is the case with lists). Using erlang:list_to_binary/1, an regular Erlang string can be converted into a binary, effectively using the ISO-latin-1 encoding in the binary - one byte per character. This is very convenient for those regular Erlang strings, but cannot be done for Unicode lists.</p> <p>As the UTF-8 encoding is widely spread and provides the most compact storage, it is selected as the standard encoding of Unicode characters in binaries for Erlang.</p> diff --git a/lib/stdlib/src/Makefile b/lib/stdlib/src/Makefile index 600303d7e1..9ce1f6f5c8 100644 --- a/lib/stdlib/src/Makefile +++ b/lib/stdlib/src/Makefile @@ -105,7 +105,6 @@ MODULES= \ qlc_pt \ queue \ random \ - regexp \ sets \ shell \ shell_default \ diff --git a/lib/stdlib/src/erl_eval.erl b/lib/stdlib/src/erl_eval.erl index 88a0094d57..bf3c7b3504 100644 --- a/lib/stdlib/src/erl_eval.erl +++ b/lib/stdlib/src/erl_eval.erl @@ -341,7 +341,7 @@ expr({call,_,{remote,_,Mod,Func},As0}, Bs0, Lf, Ef, RBs) -> true -> bif(F, As, Bs3, Ef, RBs); false -> - do_apply({M,F}, As, Bs3, Ef, RBs) + do_apply(M, F, As, Bs3, Ef, RBs) end; expr({call,_,{atom,_,Func},As0}, Bs0, Lf, Ef, RBs) -> case erl_internal:bif(Func, length(As0)) of @@ -499,11 +499,11 @@ local_func2({eval,F,As,Bs}, RBs) -> % This reply is not documented. bif(apply, [erlang,apply,As], Bs, Ef, RBs) -> bif(apply, As, Bs, Ef, RBs); bif(apply, [M,F,As], Bs, Ef, RBs) -> - do_apply({M,F}, As, Bs, Ef, RBs); + do_apply(M, F, As, Bs, Ef, RBs); bif(apply, [F,As], Bs, Ef, RBs) -> do_apply(F, As, Bs, Ef, RBs); bif(Name, As, Bs, Ef, RBs) -> - do_apply({erlang,Name}, As, Bs, Ef, RBs). + do_apply(erlang, Name, As, Bs, Ef, RBs). %% do_apply(MF, Arguments, Bindings, ExternalFuncHandler, RBs) -> %% {value,Value,Bindings} | Value when @@ -563,6 +563,19 @@ do_apply(Func, As, Bs0, Ef, RBs) -> ret_expr(F(Func, As), Bs0, RBs) end. +do_apply(Mod, Func, As, Bs0, Ef, RBs) -> + case Ef of + none when RBs =:= value -> + %% Make tail recursive calls when possible. + apply(Mod, Func, As); + none -> + ret_expr(apply(Mod, Func, As), Bs0, RBs); + {value,F} when RBs =:= value -> + F({Mod,Func}, As); + {value,F} -> + ret_expr(F({Mod,Func}, As), Bs0, RBs) + end. + %% eval_lc(Expr, [Qualifier], Bindings, LocalFunctionHandler, %% ExternalFuncHandler, RetBindings) -> %% {value,Value,Bindings} | Value @@ -731,10 +744,10 @@ expr_list([], Vs, _, Bs, _Lf, _Ef) -> {reverse(Vs),Bs}. eval_op(Op, Arg1, Arg2, Bs, Ef, RBs) -> - do_apply({erlang,Op}, [Arg1,Arg2], Bs, Ef, RBs). + do_apply(erlang, Op, [Arg1,Arg2], Bs, Ef, RBs). eval_op(Op, Arg, Bs, Ef, RBs) -> - do_apply({erlang,Op}, [Arg], Bs, Ef, RBs). + do_apply(erlang, Op, [Arg], Bs, Ef, RBs). %% if_clauses(Clauses, Bindings, LocalFuncHandler, ExtFuncHandler, RBs) @@ -920,8 +933,9 @@ guard0([], _Bs, _Lf, _Ef) -> true. guard_test({call,L,{atom,Ln,F},As0}, Bs0, Lf, Ef) -> TT = type_test(F), - guard_test({call,L,{tuple,Ln,[{atom,Ln,erlang},{atom,Ln,TT}]},As0}, - Bs0, Lf, Ef); + G = {call,L,{atom,Ln,TT},As0}, + try {value,true,_} = expr(G, Bs0, Lf, Ef, none) + catch error:_ -> {value,false,Bs0} end; guard_test({call,L,{remote,_Lr,{atom,_Lm,erlang},{atom,_Lf,_F}=T},As0}, Bs0, Lf, Ef) -> guard_test({call,L,T,As0}, Bs0, Lf, Ef); diff --git a/lib/stdlib/src/erl_lint.erl b/lib/stdlib/src/erl_lint.erl index 5d45260fe9..e5adb84932 100644 --- a/lib/stdlib/src/erl_lint.erl +++ b/lib/stdlib/src/erl_lint.erl @@ -2767,12 +2767,6 @@ default_types() -> {var, 1}], dict:from_list([{T, -1} || T <- DefTypes]). -%% R12B-5 -is_newly_introduced_builtin_type({module, 0}) -> true; -is_newly_introduced_builtin_type({node, 0}) -> true; -is_newly_introduced_builtin_type({nonempty_string, 0}) -> true; -is_newly_introduced_builtin_type({term, 0}) -> true; -is_newly_introduced_builtin_type({timeout, 0}) -> true; %% R13 is_newly_introduced_builtin_type({arity, 0}) -> true; is_newly_introduced_builtin_type({array, 0}) -> true; % opaque diff --git a/lib/stdlib/src/filename.erl b/lib/stdlib/src/filename.erl index 2fc9128e4e..dbfcbea4f7 100644 --- a/lib/stdlib/src/filename.erl +++ b/lib/stdlib/src/filename.erl @@ -836,16 +836,18 @@ try_file(undefined, ObjFilename, Mod, Rules) -> Error -> Error end; try_file(Src, _ObjFilename, Mod, _Rules) -> - List = Mod:module_info(compile), - {options, Options} = lists:keyfind(options, 1, List), + List = case Mod:module_info(compile) of + none -> []; + List0 -> List0 + end, + Options = proplists:get_value(options, List, []), {ok, Cwd} = file:get_cwd(), AbsPath = make_abs_path(Cwd, Src), {AbsPath, filter_options(dirname(AbsPath), Options, [])}. %% Filters the options. %% -%% 1) Remove options that have no effect on the generated code, -%% such as report and verbose. +%% 1) Only keep options that have any effect on code generation. %% %% 2) The paths found in {i, Path} and {outdir, Path} are converted %% to absolute paths. When doing this, it is assumed that relatives @@ -857,14 +859,10 @@ filter_options(Base, [{outdir, Path}|Rest], Result) -> filter_options(Base, Rest, [{outdir, make_abs_path(Base, Path)}|Result]); filter_options(Base, [{i, Path}|Rest], Result) -> filter_options(Base, Rest, [{i, make_abs_path(Base, Path)}|Result]); -filter_options(Base, [Option|Rest], Result) when Option =:= trace -> - filter_options(Base, Rest, [Option|Result]); filter_options(Base, [Option|Rest], Result) when Option =:= export_all -> filter_options(Base, Rest, [Option|Result]); filter_options(Base, [Option|Rest], Result) when Option =:= binary -> filter_options(Base, Rest, [Option|Result]); -filter_options(Base, [Option|Rest], Result) when Option =:= fast -> - filter_options(Base, Rest, [Option|Result]); filter_options(Base, [Tuple|Rest], Result) when element(1, Tuple) =:= d -> filter_options(Base, Rest, [Tuple|Result]); filter_options(Base, [Tuple|Rest], Result) @@ -878,12 +876,7 @@ filter_options(_Base, [], Result) -> %% Gets the source file given path of object code and module name. get_source_file(Obj, Mod, Rules) -> - case catch Mod:module_info(source_file) of - {'EXIT', _Reason} -> - source_by_rules(dirname(Obj), packages:last(Mod), Rules); - File -> - {ok, File} - end. + source_by_rules(dirname(Obj), packages:last(Mod), Rules). source_by_rules(Dir, Base, [{From, To}|Rest]) -> case try_rule(Dir, Base, From, To) of diff --git a/lib/stdlib/src/gen_event.erl b/lib/stdlib/src/gen_event.erl index 9879b76391..3317b30e5c 100644 --- a/lib/stdlib/src/gen_event.erl +++ b/lib/stdlib/src/gen_event.erl @@ -70,7 +70,8 @@ -callback init(InitArgs :: term()) -> {ok, State :: term()} | - {ok, State :: term(), hibernate}. + {ok, State :: term(), hibernate} | + {error, Reason :: term()}. -callback handle_event(Event :: term(), State :: term()) -> {ok, NewState :: term()} | {ok, NewState :: term(), hibernate} | diff --git a/lib/stdlib/src/gen_server.erl b/lib/stdlib/src/gen_server.erl index 6f075bbe5a..af07bc988a 100644 --- a/lib/stdlib/src/gen_server.erl +++ b/lib/stdlib/src/gen_server.erl @@ -134,7 +134,7 @@ term(). -callback code_change(OldVsn :: (term() | {down, term()}), State :: term(), Extra :: term()) -> - {ok, NewState :: term()}. + {ok, NewState :: term()} | {error, Reason :: term()}. %%% ----------------------------------------------------------------- %%% Starts a generic server. diff --git a/lib/stdlib/src/otp_internal.erl b/lib/stdlib/src/otp_internal.erl index c1285dab60..7bacc05ff2 100644 --- a/lib/stdlib/src/otp_internal.erl +++ b/lib/stdlib/src/otp_internal.erl @@ -41,37 +41,12 @@ obsolete(Module, Name, Arity) -> no end. -obsolete_1(init, get_flag, 1) -> - {removed, {init, get_argument, 1}, "R12B"}; -obsolete_1(init, get_flags, 0) -> - {removed, {init, get_arguments, 0}, "R12B"}; -obsolete_1(init, get_args, 0) -> - {removed, {init, get_plain_arguments, 0}, "R12B"}; -obsolete_1(unix, cmd, 1) -> - {removed, {os,cmd,1}, "R9B"}; - obsolete_1(net, _, _) -> {deprecated, "module 'net' obsolete; use 'net_adm'"}; obsolete_1(erl_internal, builtins, 0) -> {deprecated, {erl_internal, bif, 2}}; -obsolete_1(string, re_sh_to_awk, 1) -> - {removed, {regexp, sh_to_awk, 1}, "R12B"}; -obsolete_1(string, re_parse, 1) -> - {removed, {regexp, parse, 1}, "R12B"}; -obsolete_1(string, re_match, 2) -> - {removed, {regexp, match, 2}, "R12B"}; -obsolete_1(string, re_sub, 3) -> - {removed, {regexp, sub, 3}, "R12B"}; -obsolete_1(string, re_gsub, 3) -> - {removed, {regexp, gsub, 3}, "R12B"}; -obsolete_1(string, re_split, 2) -> - {removed, {regexp, split, 2}, "R12B"}; - -obsolete_1(string, index, 2) -> - {removed, {string, str, 2}, "R12B"}; - obsolete_1(erl_eval, seq, 2) -> {deprecated, {erl_eval, exprs, 2}}; obsolete_1(erl_eval, seq, 3) -> @@ -81,99 +56,9 @@ obsolete_1(erl_eval, arg_list, 2) -> obsolete_1(erl_eval, arg_list, 3) -> {deprecated, {erl_eval, expr_list, 3}}; -obsolete_1(erl_pp, seq, 1) -> - {removed, {erl_pp, exprs, 1}, "R12B"}; -obsolete_1(erl_pp, seq, 2) -> - {removed, {erl_pp, exprs, 2}, "R12B"}; - -obsolete_1(io, scan_erl_seq, 1) -> - {removed, {io, scan_erl_exprs, 1}, "R12B"}; -obsolete_1(io, scan_erl_seq, 2) -> - {removed, {io, scan_erl_exprs, 2}, "R12B"}; -obsolete_1(io, scan_erl_seq, 3) -> - {removed, {io, scan_erl_exprs, 3}, "R12B"}; -obsolete_1(io, parse_erl_seq, 1) -> - {removed, {io, parse_erl_exprs, 1}, "R12B"}; -obsolete_1(io, parse_erl_seq, 2) -> - {removed, {io, parse_erl_exprs, 2}, "R12B"}; -obsolete_1(io, parse_erl_seq, 3) -> - {removed, {io, parse_erl_exprs, 3}, "R12B"}; -obsolete_1(io, parse_exprs, 2) -> - {removed, {io, parse_erl_exprs, 2}, "R12B"}; - -obsolete_1(io_lib, scan, 1) -> - {removed, {erl_scan, string, 1}, "R12B"}; -obsolete_1(io_lib, scan, 2) -> - {removed, {erl_scan, string, 2}, "R12B"}; -obsolete_1(io_lib, scan, 3) -> - {removed, {erl_scan, tokens, 3}, "R12B"}; -obsolete_1(io_lib, reserved_word, 1) -> - {removed, {erl_scan, reserved_word, 1}, "R12B"}; - -obsolete_1(lists, keymap, 4) -> - {removed, {lists, keymap, 3}, "R12B"}; -obsolete_1(lists, all, 3) -> - {removed, {lists, all, 2}, "R12B"}; -obsolete_1(lists, any, 3) -> - {removed, {lists, any, 2}, "R12B"}; -obsolete_1(lists, map, 3) -> - {removed, {lists, map, 2}, "R12B"}; -obsolete_1(lists, flatmap, 3) -> - {removed, {lists, flatmap, 2}, "R12B"}; -obsolete_1(lists, foldl, 4) -> - {removed, {lists, foldl, 3}, "R12B"}; -obsolete_1(lists, foldr, 4) -> - {removed, {lists, foldr, 3}, "R12B"}; -obsolete_1(lists, mapfoldl, 4) -> - {removed, {lists, mapfoldl, 3}, "R12B"}; -obsolete_1(lists, mapfoldr, 4) -> - {removed, {lists, mapfoldr, 3}, "R12B"}; -obsolete_1(lists, filter, 3) -> - {removed, {lists, filter, 2}, "R12B"}; -obsolete_1(lists, foreach, 3) -> - {removed, {lists, foreach, 2}, "R12B"}; -obsolete_1(lists, zf, 3) -> - {removed, {lists, zf, 2}, "R12B"}; - -obsolete_1(ets, fixtable, 2) -> - {removed, {ets, safe_fixtable, 2}, "R12B"}; - -obsolete_1(erlang, old_binary_to_term, 1) -> - {removed, {erlang, binary_to_term, 1}, "R12B"}; -obsolete_1(erlang, info, 1) -> - {removed, {erlang, system_info, 1}, "R12B"}; obsolete_1(erlang, hash, 2) -> {deprecated, {erlang, phash2, 2}}; -obsolete_1(file, file_info, 1) -> - {removed, {file, read_file_info, 1}, "R12B"}; - -obsolete_1(dict, dict_to_list, 1) -> - {removed, {dict,to_list,1}, "R12B"}; -obsolete_1(dict, list_to_dict, 1) -> - {removed, {dict,from_list,1}, "R12B"}; -obsolete_1(orddict, dict_to_list, 1) -> - {removed, {orddict,to_list,1}, "R12B"}; -obsolete_1(orddict, list_to_dict, 1) -> - {removed, {orddict,from_list,1}, "R12B"}; - -obsolete_1(sets, new_set, 0) -> - {removed, {sets, new, 0}, "R12B"}; -obsolete_1(sets, set_to_list, 1) -> - {removed, {sets, to_list, 1}, "R12B"}; -obsolete_1(sets, list_to_set, 1) -> - {removed, {sets, from_list, 1}, "R12B"}; -obsolete_1(sets, subset, 2) -> - {removed, {sets, is_subset, 2}, "R12B"}; -obsolete_1(ordsets, new_set, 0) -> - {removed, {ordsets, new, 0}, "R12B"}; -obsolete_1(ordsets, set_to_list, 1) -> - {removed, {ordsets, to_list, 1}, "R12B"}; -obsolete_1(ordsets, list_to_set, 1) -> - {removed, {ordsets, from_list, 1}, "R12B"}; -obsolete_1(ordsets, subset, 2) -> - {removed, {ordsets, is_subset, 2}, "R12B"}; - obsolete_1(calendar, local_time_to_universal_time, 1) -> {deprecated, {calendar, local_time_to_universal_time_dst, 1}}; @@ -302,17 +187,6 @@ obsolete_1(auth, node_cookie, 1) -> obsolete_1(auth, node_cookie, 2) -> {deprecated, "Deprecated; use erlang:set_cookie/2 and net_adm:ping/1 instead"}; -%% Added in R11B-5. -obsolete_1(http_base_64, _, _) -> - {removed, "The http_base_64 module was removed in R12B; use the base64 module instead"}; -obsolete_1(httpd_util, encode_base64, 1) -> - {removed, "Removed in R12B; use one of the encode functions in the base64 module instead"}; -obsolete_1(httpd_util, decode_base64, 1) -> - {removed, "Removed in R12B; use one of the decode functions in the base64 module instead"}; -obsolete_1(httpd_util, to_upper, 1) -> - {removed, {string, to_upper, 1}, "R12B"}; -obsolete_1(httpd_util, to_lower, 1) -> - {removed, {string, to_lower, 1}, "R12B"}; obsolete_1(erlang, is_constant, 1) -> {removed, "Removed in R13B"}; @@ -431,7 +305,7 @@ obsolete_1(ssh_sshd, stop, 1) -> %% Added in R13A. obsolete_1(regexp, _, _) -> - {deprecated, "the regexp module is deprecated (will be removed in R15A); use the re module instead"}; + {removed, "removed in R15; use the re module instead"}; obsolete_1(lists, flat_length, 1) -> {removed,{lists,flatlength,1},"R14"}; @@ -472,7 +346,10 @@ obsolete_1(docb_xml_check, _, _) -> %% Added in R15B obsolete_1(asn1rt, F, _) when F == load_driver; F == unload_driver -> {deprecated,"deprecated (will be removed in R16A); has no effect as drivers are no longer used."}; - +obsolete_1(ssl, pid, 1) -> + {deprecated,"deprecated (will be removed in R17); is no longer needed"}; +obsolete_1(inviso, _, _) -> + {deprecated,"the inviso application has been deprecated and will be removed in R16"}; obsolete_1(_, _, _) -> no. diff --git a/lib/stdlib/src/regexp.erl b/lib/stdlib/src/regexp.erl deleted file mode 100644 index 65f9ca247d..0000000000 --- a/lib/stdlib/src/regexp.erl +++ /dev/null @@ -1,557 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1996-2011. All Rights Reserved. -%% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% --module(regexp). - -%% This entire module is deprecated and will be removed in a future -%% release. Use the 're' module instead. -%% -%% This module provides a basic set of regular expression functions -%% for strings. The functions provided are taken from AWK. -%% -%% Note that we interpret the syntax tree of a regular expression -%% directly instead of converting it to an NFA and then interpreting -%% that. This method seems to go significantly faster. - --export([sh_to_awk/1,parse/1,format_error/1,match/2,first_match/2,matches/2]). --export([sub/3,gsub/3,split/2]). - --deprecated([sh_to_awk/1,parse/1,format_error/1,match/2,first_match/2,matches/2]). --deprecated([sub/3,gsub/3,split/2]). - --import(string, [substr/2,substr/3]). --import(lists, [reverse/1]). - --type errordesc() :: term(). --opaque regexp() :: term(). - -%% -type matchres() = {match,Start,Length} | nomatch | {error,E}. -%% -type subres() = {ok,RepString,RepCount} | {error,E}. -%% -type splitres() = {ok,[SubString]} | {error,E}. - -%%-compile([export_all]). - -%% This is the regular expression grammar used. It is equivalent to the -%% one used in AWK, except that we allow ^ $ to be used anywhere and fail -%% in the matching. -%% -%% reg -> reg1 : '$1'. -%% reg1 -> reg1 "|" reg2 : {'or','$1','$2'}. -%% reg1 -> reg2 : '$1'. -%% reg2 -> reg2 reg3 : {concat,'$1','$2'}. -%% reg2 -> reg3 : '$1'. -%% reg3 -> reg3 "*" : {kclosure,'$1'}. -%% reg3 -> reg3 "+" : {pclosure,'$1'}. -%% reg3 -> reg3 "?" : {optional,'$1'}. -%% reg3 -> reg4 : '$1'. -%% reg4 -> "(" reg ")" : '$2'. -%% reg4 -> "\\" char : '$2'. -%% reg4 -> "^" : bos. -%% reg4 -> "$" : eos. -%% reg4 -> "." : char. -%% reg4 -> "[" class "]" : {char_class,char_class('$2')} -%% reg4 -> "[" "^" class "]" : {comp_class,char_class('$3')} -%% reg4 -> "\"" chars "\"" : char_string('$2') -%% reg4 -> char : '$1'. -%% reg4 -> empty : epsilon. -%% The grammar of the current regular expressions. The actual parser -%% is a recursive descent implementation of the grammar. - -reg(S) -> reg1(S). - -%% reg1 -> reg2 reg1' -%% reg1' -> "|" reg2 -%% reg1' -> empty - -reg1(S0) -> - {L,S1} = reg2(S0), - reg1p(S1, L). - -reg1p([$||S0], L) -> - {R,S1} = reg2(S0), - reg1p(S1, {'or',L,R}); -reg1p(S, L) -> {L,S}. - -%% reg2 -> reg3 reg2' -%% reg2' -> reg3 -%% reg2' -> empty - -reg2(S0) -> - {L,S1} = reg3(S0), - reg2p(S1, L). - -reg2p([C|S0], L) when C =/= $|, C =/= $) -> - {R,S1} = reg3([C|S0]), - reg2p(S1, {concat,L,R}); -reg2p(S, L) -> {L,S}. - -%% reg3 -> reg4 reg3' -%% reg3' -> "*" reg3' -%% reg3' -> "+" reg3' -%% reg3' -> "?" reg3' -%% reg3' -> empty - -reg3(S0) -> - {L,S1} = reg4(S0), - reg3p(S1, L). - -reg3p([$*|S], L) -> reg3p(S, {kclosure,L}); -reg3p([$+|S], L) -> reg3p(S, {pclosure,L}); -reg3p([$?|S], L) -> reg3p(S, {optional,L}); -reg3p(S, L) -> {L,S}. - --define(HEX(C), C >= $0 andalso C =< $9 orelse - C >= $A andalso C =< $F orelse - C >= $a andalso C =< $f). - -reg4([$(|S0]) -> - case reg(S0) of - {R,[$)|S1]} -> {R,S1}; - {_R,_S} -> throw({error,{unterminated,"("}}) - end; -reg4([$\\,O1,O2,O3|S]) when - O1 >= $0, O1 =< $7, O2 >= $0, O2 =< $7, O3 >= $0, O3 =< $7 -> - {(O1*8 + O2)*8 + O3 - 73*$0,S}; -reg4([$\\,$x,H1,H2|S]) when ?HEX(H1), ?HEX(H2) -> - {erlang:list_to_integer([H1,H2], 16),S}; -reg4([$\\,$x,${|S]) -> - hex(S, []); -reg4([$\\,$x|_]) -> - throw({error,{illegal,[$x]}}); -reg4([$\\,C|S]) -> {escape_char(C),S}; -reg4([$\\]) -> throw({error,{unterminated,"\\"}}); -reg4([$^|S]) -> {bos,S}; -reg4([$$|S]) -> {eos,S}; -reg4([$.|S]) -> {{comp_class,"\n"},S}; -reg4("[^" ++ S0) -> - case char_class(S0) of - {Cc,[$]|S1]} -> {{comp_class,Cc},S1}; - {_Cc,_S} -> throw({error,{unterminated,"["}}) - end; -reg4([$[|S0]) -> - case char_class(S0) of - {Cc,[$]|S1]} -> {{char_class,Cc},S1}; - {_Cc,_S1} -> throw({error,{unterminated,"["}}) - end; -%reg4([$"|S0]) -> -% case char_string(S0) of -% {St,[$"|S1]} -> {St,S1}; -% {St,S1} -> throw({error,{unterminated,"\""}}) -% end; -reg4([C|S]) when C =/= $*, C =/= $+, C =/= $?, C =/= $] -> {C,S}; -reg4([C|_S]) -> throw({error,{illegal,[C]}}); -reg4([]) -> {epsilon,[]}. - -hex([C|Cs], L) when ?HEX(C) -> - hex(Cs, [C|L]); -hex([$}|S], L) -> - case catch erlang:list_to_integer(lists:reverse(L), 16) of - V when V =< 16#FF -> - {V,S}; - _ -> - throw({error,{illegal,[$}]}}) - end; -hex(_S, _) -> - throw({error,{unterminated,"\\x{"}}). - -escape_char($n) -> $\n; %\n = LF -escape_char($r) -> $\r; %\r = CR -escape_char($t) -> $\t; %\t = TAB -escape_char($v) -> $\v; %\v = VT -escape_char($b) -> $\b; %\b = BS -escape_char($f) -> $\f; %\f = FF -escape_char($e) -> $\e; %\e = ESC -escape_char($s) -> $\s; %\s = SPACE -escape_char($d) -> $\d; %\d = DEL -escape_char(C) -> C. - -char_class([$]|S]) -> char_class(S, [$]]); -char_class(S) -> char_class(S, []). - -char($\\, [O1,O2,O3|S]) when - O1 >= $0, O1 =< $7, O2 >= $0, O2 =< $7, O3 >= $0, O3 =< $7 -> - {(O1*8 + O2)*8 + O3 - 73*$0,S}; -char($\\, [$x,H1,H2|S]) when ?HEX(H1), ?HEX(H2) -> - {erlang:list_to_integer([H1,H2], 16),S}; -char($\\,[$x,${|S]) -> - hex(S, []); -char($\\,[$x|_]) -> - throw({error,{illegal,[$x]}}); -char($\\, [C|S]) -> {escape_char(C),S}; -char(C, S) -> {C,S}. - -char_class([C1|S0], Cc) when C1 =/= $] -> - case char(C1, S0) of - {Cf,[$-,C2|S1]} when C2 =/= $] -> - case char(C2, S1) of - {Cl,S2} when Cf < Cl -> char_class(S2, [{Cf,Cl}|Cc]); - {Cl,_S2} -> throw({error,{char_class,[Cf,$-,Cl]}}) - end; - {C,S1} -> char_class(S1, [C|Cc]) - end; -char_class(S, Cc) -> {Cc,S}. - -%char_string([C|S]) when C =/= $" -> char_string(S, C); -%char_string(S) -> {epsilon,S}. - -%char_string([C|S0], L) when C =/= $" -> -% char_string(S0, {concat,L,C}); -%char_string(S, L) -> {L,S}. - -%% -deftype re_app_res() = {match,RestPos,Rest} | nomatch. - -%% re_apply(String, StartPos, RegExp) -> re_app_res(). -%% -%% Apply the (parse of the) regular expression RegExp to String. If -%% there is a match return the position of the remaining string and -%% the string if else return 'nomatch'. BestMatch specifies if we want -%% the longest match, or just a match. -%% -%% StartPos should be the real start position as it is used to decide -%% if we ae at the beginning of the string. -%% -%% Pass two functions to re_apply_or so it can decide, on the basis -%% of BestMatch, whether to just any take any match or try both to -%% find the longest. This is slower but saves duplicatng code. - -re_apply(S, St, RE) -> re_apply(RE, [], S, St). - -re_apply(epsilon, More, S, P) -> %This always matches - re_apply_more(More, S, P); -re_apply({'or',RE1,RE2}, More, S, P) -> - re_apply_or(re_apply(RE1, More, S, P), - re_apply(RE2, More, S, P)); -re_apply({concat,RE1,RE2}, More, S0, P) -> - re_apply(RE1, [RE2|More], S0, P); -re_apply({kclosure,CE}, More, S, P) -> - %% Be careful with the recursion, explicitly do one call before - %% looping. - re_apply_or(re_apply_more(More, S, P), - re_apply(CE, [{kclosure,CE}|More], S, P)); -re_apply({pclosure,CE}, More, S, P) -> - re_apply(CE, [{kclosure,CE}|More], S, P); -re_apply({optional,CE}, More, S, P) -> - re_apply_or(re_apply_more(More, S, P), - re_apply(CE, More, S, P)); -re_apply(bos, More, S, 1) -> re_apply_more(More, S, 1); -re_apply(eos, More, [$\n|S], P) -> re_apply_more(More, S, P); -re_apply(eos, More, [], P) -> re_apply_more(More, [], P); -re_apply({char_class,Cc}, More, [C|S], P) -> - case in_char_class(C, Cc) of - true -> re_apply_more(More, S, P+1); - false -> nomatch - end; -re_apply({comp_class,Cc}, More, [C|S], P) -> - case in_char_class(C, Cc) of - true -> nomatch; - false -> re_apply_more(More, S, P+1) - end; -re_apply(C, More, [C|S], P) when is_integer(C) -> - re_apply_more(More, S, P+1); -re_apply(_RE, _More, _S, _P) -> nomatch. - -%% re_apply_more([RegExp], String, Length) -> re_app_res(). - -re_apply_more([RE|More], S, P) -> re_apply(RE, More, S, P); -re_apply_more([], S, P) -> {match,P,S}. - -%% in_char_class(Char, Class) -> bool(). - -in_char_class(C, [{C1,C2}|_Cc]) when C >= C1, C =< C2 -> true; -in_char_class(C, [C|_Cc]) -> true; -in_char_class(C, [_|Cc]) -> in_char_class(C, Cc); -in_char_class(_C, []) -> false. - -%% re_apply_or(Match1, Match2) -> re_app_res(). -%% If we want the best match then choose the longest match, else just -%% choose one by trying sequentially. - -re_apply_or({match,P1,S1}, {match,P2,_S2}) when P1 >= P2 -> {match,P1,S1}; -re_apply_or({match,_P1,_S1}, {match,P2,S2}) -> {match,P2,S2}; -re_apply_or(nomatch, R2) -> R2; -re_apply_or(R1, nomatch) -> R1. - -%% sh_to_awk(ShellRegExp) -%% Convert a sh style regexp into a full AWK one. The main difficulty is -%% getting character sets right as the conventions are different. - --spec sh_to_awk(ShRegExp) -> AwkRegExp when - ShRegExp :: string(), - AwkRegExp :: string(). - -sh_to_awk(Sh) -> "^(" ++ sh_to_awk_1(Sh). %Fix the beginning - -sh_to_awk_1([$*|Sh]) -> %This matches any string - ".*" ++ sh_to_awk_1(Sh); -sh_to_awk_1([$?|Sh]) -> %This matches any character - [$.|sh_to_awk_1(Sh)]; -sh_to_awk_1([$[,$^,$]|Sh]) -> %This takes careful handling - "\\^" ++ sh_to_awk_1(Sh); -sh_to_awk_1("[^" ++ Sh) -> [$[|sh_to_awk_2(Sh, true)]; -sh_to_awk_1("[!" ++ Sh) -> "[^" ++ sh_to_awk_2(Sh, false); -sh_to_awk_1([$[|Sh]) -> [$[|sh_to_awk_2(Sh, false)]; -sh_to_awk_1([C|Sh]) -> - %% Unspecialise everything else which is not an escape character. - case special_char(C) of - true -> [$\\,C|sh_to_awk_1(Sh)]; - false -> [C|sh_to_awk_1(Sh)] - end; -sh_to_awk_1([]) -> ")$". %Fix the end - -sh_to_awk_2([$]|Sh], UpArrow) -> [$]|sh_to_awk_3(Sh, UpArrow)]; -sh_to_awk_2(Sh, UpArrow) -> sh_to_awk_3(Sh, UpArrow). - -sh_to_awk_3([$]|Sh], true) -> "^]" ++ sh_to_awk_1(Sh); -sh_to_awk_3([$]|Sh], false) -> [$]|sh_to_awk_1(Sh)]; -sh_to_awk_3([C|Sh], UpArrow) -> [C|sh_to_awk_3(Sh, UpArrow)]; -sh_to_awk_3([], true) -> [$^|sh_to_awk_1([])]; -sh_to_awk_3([], false) -> sh_to_awk_1([]). - -%% -type special_char(char()) -> bool(). -%% Test if a character is a special character. - -special_char($|) -> true; -special_char($*) -> true; -special_char($+) -> true; -special_char($?) -> true; -special_char($() -> true; -special_char($)) -> true; -special_char($\\) -> true; -special_char($^) -> true; -special_char($$) -> true; -special_char($.) -> true; -special_char($[) -> true; -special_char($]) -> true; -special_char($") -> true; -special_char(_C) -> false. - -%% parse(RegExp) -> {ok,RE} | {error,E}. -%% Parse the regexp described in the string RegExp. - --spec parse(RegExp) -> ParseRes when - RegExp :: string(), - ParseRes :: {ok, RE} | {error, Error}, - RE :: regexp(), - Error :: errordesc(). - -parse(S) -> - case catch reg(S) of - {R,[]} -> {ok,R}; - {_R,[C|_]} -> {error,{illegal,[C]}}; - {error,E} -> {error,E} - end. - -%% format_error(Error) -> String. - --spec format_error(ErrorDescriptor) -> Chars when - ErrorDescriptor :: errordesc(), - Chars :: io_lib:chars(). - -format_error({illegal,What}) -> ["illegal character `",What,"'"]; -format_error({unterminated,What}) -> ["unterminated `",What,"'"]; -format_error({char_class,What}) -> - ["illegal character class ",io_lib:write_string(What)]. - -%% -type match(String, RegExp) -> matchres(). -%% Find the longest match of RegExp in String. - --spec match(String, RegExp) -> MatchRes when - String :: string(), - RegExp :: string() | regexp(), - MatchRes :: {match, Start, Length} | nomatch | {error, Error}, - Start :: pos_integer(), - Length :: pos_integer(), - Error :: errordesc(). - -match(S, RegExp) when is_list(RegExp) -> - case parse(RegExp) of - {ok,RE} -> match(S, RE); - {error,E} -> {error,E} - end; -match(S, RE) -> - case match(RE, S, 1, 0, -1) of - {Start,Len} when Len >= 0 -> - {match,Start,Len}; - {_Start,_Len} -> nomatch - end. - -match(RE, S, St, Pos, L) -> - case first_match(RE, S, St) of - {St1,L1} -> - Nst = St1 + 1, - if L1 > L -> match(RE, lists:nthtail(Nst-St, S), Nst, St1, L1); - true -> match(RE, lists:nthtail(Nst-St, S), Nst, Pos, L) - end; - nomatch -> {Pos,L} - end. - -%% -type first_match(String, RegExp) -> matchres(). -%% Find the first match of RegExp in String. - --spec first_match(String, RegExp) -> MatchRes when - String :: string(), - RegExp :: string() | regexp(), - MatchRes :: {match, Start, Length} | nomatch | {error, Error}, - Start :: pos_integer(), - Length :: pos_integer(), - Error :: errordesc(). - -first_match(S, RegExp) when is_list(RegExp) -> - case parse(RegExp) of - {ok,RE} -> first_match(S, RE); - {error,E} -> {error,E} - end; -first_match(S, RE) -> - case first_match(RE, S, 1) of - {Start,Len} when Len >= 0 -> - {match,Start,Len}; - nomatch -> nomatch - end. - -first_match(RE, S, St) when S =/= [] -> - case re_apply(S, St, RE) of - {match,P,_Rest} -> {St,P-St}; - nomatch -> first_match(RE, tl(S), St+1) - end; -first_match(_RE, [], _St) -> nomatch. - -%% -type matches(String, RegExp) -> {match,[{Start,Length}]} | {error,E}. -%% Return the all the non-overlapping matches of RegExp in String. - --spec matches(String, RegExp) -> MatchRes when - String :: string(), - RegExp :: string() | regexp(), - MatchRes :: {match, Matches} | {error, Error}, - Matches :: [{Start, Length}], - Start :: pos_integer(), - Length :: pos_integer(), - Error :: errordesc(). - -matches(S, RegExp) when is_list(RegExp) -> - case parse(RegExp) of - {ok,RE} -> matches(S, RE); - {error,E} -> {error,E} - end; -matches(S, RE) -> - {match,matches(S, RE, 1)}. - -matches(S, RE, St) -> - case first_match(RE, S, St) of - {St1,0} -> [{St1,0}|matches(substr(S, St1+2-St), RE, St1+1)]; - {St1,L1} -> [{St1,L1}|matches(substr(S, St1+L1+1-St), RE, St1+L1)]; - nomatch -> [] - end. - -%% -type sub(String, RegExp, Replace) -> subsres(). -%% Substitute the first match of the regular expression RegExp with -%% the string Replace in String. Accept pre-parsed regular -%% expressions. - --spec sub(String, RegExp, New) -> SubRes when - String :: string(), - RegExp :: string() | regexp(), - New :: string(), - NewString :: string(), - SubRes :: {ok, NewString, RepCount} | {error, Error}, - RepCount :: 0 | 1, - Error :: errordesc(). - -sub(String, RegExp, Rep) when is_list(RegExp) -> - case parse(RegExp) of - {ok,RE} -> sub(String, RE, Rep); - {error,E} -> {error,E} - end; -sub(String, RE, Rep) -> - Ss = sub_match(String, RE, 1), - {ok,sub_repl(Ss, Rep, String, 1),length(Ss)}. - -sub_match(S, RE, St) -> - case first_match(RE, S, St) of - {St1,L1} -> [{St1,L1}]; - nomatch -> [] - end. - -sub_repl([{St,L}|Ss], Rep, S, Pos) -> - Rs = sub_repl(Ss, Rep, S, St+L), - substr(S, Pos, St-Pos) ++ sub_repl(Rep, substr(S, St, L), Rs); -sub_repl([], _Rep, S, Pos) -> substr(S, Pos). - -sub_repl([$&|Rep], M, Rest) -> M ++ sub_repl(Rep, M, Rest); -sub_repl("\\&" ++ Rep, M, Rest) -> [$&|sub_repl(Rep, M, Rest)]; -sub_repl([C|Rep], M, Rest) -> [C|sub_repl(Rep, M, Rest)]; -sub_repl([], _M, Rest) -> Rest. - -%% -type gsub(String, RegExp, Replace) -> subres(). -%% Substitute every match of the regular expression RegExp with the -%% string New in String. Accept pre-parsed regular expressions. - --spec gsub(String, RegExp, New) -> SubRes when - String :: string(), - RegExp :: string() | regexp(), - New :: string(), - NewString :: string(), - SubRes :: {ok, NewString, RepCount} | {error, Error}, - RepCount :: non_neg_integer(), - Error :: errordesc(). - -gsub(String, RegExp, Rep) when is_list(RegExp) -> - case parse(RegExp) of - {ok,RE} -> gsub(String, RE, Rep); - {error,E} -> {error,E} - end; -gsub(String, RE, Rep) -> - Ss = matches(String, RE, 1), - {ok,sub_repl(Ss, Rep, String, 1),length(Ss)}. - -%% -type split(String, RegExp) -> splitres(). -%% Split a string into substrings where the RegExp describes the -%% field seperator. The RegExp " " is specially treated. - --spec split(String, RegExp) -> SplitRes when - String :: string(), - RegExp :: string() | regexp(), - SplitRes :: {ok, FieldList} | {error, Error}, - FieldList :: [string()], - Error :: errordesc(). - -split(String, " ") -> %This is really special - {ok,RE} = parse("[ \t]+"), - case split_apply(String, RE, true) of - [[]|Ss] -> {ok,Ss}; - Ss -> {ok,Ss} - end; -split(String, RegExp) when is_list(RegExp) -> - case parse(RegExp) of - {ok,RE} -> {ok,split_apply(String, RE, false)}; - {error,E} -> {error,E} - end; -split(String, RE) -> {ok,split_apply(String, RE, false)}. - -split_apply(S, RE, Trim) -> split_apply(S, 1, RE, Trim, []). - -split_apply([], _P, _RE, true, []) -> []; -split_apply([], _P, _RE, _T, Sub) -> [reverse(Sub)]; -split_apply(S, P, RE, T, Sub) -> - case re_apply(S, P, RE) of - {match,P,_Rest} -> - split_apply(tl(S), P+1, RE, T, [hd(S)|Sub]); - {match,P1,Rest} -> - [reverse(Sub)|split_apply(Rest, P1, RE, T, [])]; - nomatch -> - split_apply(tl(S), P+1, RE, T, [hd(S)|Sub]) - end. diff --git a/lib/stdlib/src/shell.erl b/lib/stdlib/src/shell.erl index 964697cae6..dc450f0ee6 100644 --- a/lib/stdlib/src/shell.erl +++ b/lib/stdlib/src/shell.erl @@ -1065,9 +1065,10 @@ local_func(F, As0, Bs0, _Shell, _RT, Lf, Ef) when is_atom(F) -> non_builtin_local_func(F,As,Bs). non_builtin_local_func(F,As,Bs) -> - case erlang:function_exported(user_default, F, length(As)) of + Arity = length(As), + case erlang:function_exported(user_default, F, Arity) of true -> - {eval,{user_default,F},As,Bs}; + {eval,erlang:make_fun(user_default, F, Arity),As,Bs}; false -> shell_default(F,As,Bs) end. @@ -1079,7 +1080,7 @@ shell_default(F,As,Bs) -> {module, _} -> case erlang:function_exported(M,F,A) of true -> - {eval,{M,F},As,Bs}; + {eval,erlang:make_fun(M, F, A),As,Bs}; false -> shell_undef(F,A) end; diff --git a/lib/stdlib/src/stdlib.app.src b/lib/stdlib/src/stdlib.app.src index 9d15f01683..da65db4b9d 100644 --- a/lib/stdlib/src/stdlib.app.src +++ b/lib/stdlib/src/stdlib.app.src @@ -85,7 +85,6 @@ queue, random, re, - regexp, sets, shell, shell_default, diff --git a/lib/stdlib/src/stdlib.appup.src b/lib/stdlib/src/stdlib.appup.src index 54a63833e6..94e81188b5 100644 --- a/lib/stdlib/src/stdlib.appup.src +++ b/lib/stdlib/src/stdlib.appup.src @@ -1 +1,27 @@ -{"%VSN%",[],[]}. +%% -*- erlang -*- +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2011. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +{"%VSN%", + %% Up from - max two major revisions back + [{<<"1\\.18(\\.[0-9]+)*">>,[restart_new_emulator]}, %% R15 + {<<"1\\.17(\\.[0-9]+)*">>,[restart_new_emulator]}, %% R14 + {<<"1\\.16(\\.[0-9]+)*">>,[restart_new_emulator]}],%% R13 + %% Down to - max two major revisions back + [{<<"1\\.18(\\.[0-9]+)*">>,[restart_new_emulator]}, %% R15 + {<<"1\\.17(\\.[0-9]+)*">>,[restart_new_emulator]}, %% R14 + {<<"1\\.16(\\.[0-9]+)*">>,[restart_new_emulator]}] %% R13 +}. diff --git a/lib/stdlib/src/supervisor.erl b/lib/stdlib/src/supervisor.erl index 2dd5ccce7a..42ea42f42e 100644 --- a/lib/stdlib/src/supervisor.erl +++ b/lib/stdlib/src/supervisor.erl @@ -37,7 +37,7 @@ %%-------------------------------------------------------------------------- --type child() :: pid() | 'undefined'. +-type child() :: 'undefined' | pid() | [pid()]. -type child_id() :: term(). -type mfargs() :: {M :: module(), F :: atom(), A :: [term()] | undefined}. -type modules() :: [module()] | 'dynamic'. diff --git a/lib/stdlib/test/binary_module_SUITE.erl b/lib/stdlib/test/binary_module_SUITE.erl index 8fb63f33bd..bac59a3107 100644 --- a/lib/stdlib/test/binary_module_SUITE.erl +++ b/lib/stdlib/test/binary_module_SUITE.erl @@ -20,7 +20,7 @@ -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, init_per_group/2,end_per_group/2, - interesting/1,random_ref_comp/1,random_ref_sr_comp/1, + interesting/1,scope_return/1,random_ref_comp/1,random_ref_sr_comp/1, random_ref_fla_comp/1,parts/1, bin_to_list/1, list_to_bin/1, copy/1, referenced/1,guard/1,encode_decode/1,badargs/1,longest_common_trap/1]). @@ -67,7 +67,7 @@ end_per_testcase(_Case, Config) -> suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> - [interesting, random_ref_fla_comp, random_ref_sr_comp, + [scope_return,interesting, random_ref_fla_comp, random_ref_sr_comp, random_ref_comp, parts, bin_to_list, list_to_bin, copy, referenced, guard, encode_decode, badargs, longest_common_trap]. @@ -379,6 +379,20 @@ subj() -> Subject. +scope_return(doc) -> + ["Test correct return values for scopes (OTP-9701)."]; +scope_return(Config) when is_list(Config) -> + N=10000, + Bin=binary:copy(<<"a">>,N), + scope_loop(Bin,0,N). + +scope_loop(_,N,N) -> + ok; +scope_loop(Bin,N,M) -> + ?line {N,1} = binary:match(Bin,<<"a">>,[{scope,{N,1}}]), + ?line {N,1} = binary:match(Bin,[<<"a">>,<<"b">>],[{scope,{N,1}}]), + scope_loop(Bin,N+1,M). + interesting(doc) -> ["Try some interesting patterns"]; interesting(Config) when is_list(Config) -> diff --git a/lib/stdlib/test/filename_SUITE.erl b/lib/stdlib/test/filename_SUITE.erl index 70b0d413dc..4cfa589660 100644 --- a/lib/stdlib/test/filename_SUITE.erl +++ b/lib/stdlib/test/filename_SUITE.erl @@ -483,6 +483,22 @@ find_src(Config) when is_list(Config) -> %% Try to find the source for a preloaded module. ?line {error,{preloaded,init}} = filename:find_src(init), + + %% Make sure that find_src works for a slim BEAM file. + OldPath = code:get_path(), + try + PrivDir = ?config(priv_dir, Config), + code:add_patha(PrivDir), + Src = "simple", + SrcPath = filename:join(PrivDir, Src) ++ ".erl", + SrcContents = "-module(simple).\n", + ok = file:write_file(SrcPath, SrcContents), + {ok,simple} = compile:file(SrcPath, [slim,{outdir,PrivDir}]), + BeamPath = filename:join(PrivDir, Src), + {BeamPath,[]} = filename:find_src(simple) + after + code:set_path(OldPath) + end, ok. %% diff --git a/lib/stdlib/test/qlc_SUITE.erl b/lib/stdlib/test/qlc_SUITE.erl index 8a9d8f7883..50a76cdfb5 100644 --- a/lib/stdlib/test/qlc_SUITE.erl +++ b/lib/stdlib/test/qlc_SUITE.erl @@ -20,7 +20,6 @@ %%% Purpose:Test Suite for the 'qlc' module. %%%----------------------------------------------------------------- -module(qlc_SUITE). --compile(r12). -define(QLC, qlc). -define(QLCs, "qlc"). @@ -6118,6 +6117,7 @@ otp_6964(Config) when is_list(Config) -> qlc:e(Q, [{max_list_size,64*1024},{tmpdir_usage,Use}]) end, D = erlang:system_flag(backtrace_depth, 0), + try 20000 = length(F(allowed)), ErrReply = F(not_allowed), {error, qlc, {tmpdir_usage,joining}} = ErrReply, @@ -6129,8 +6129,10 @@ otp_6964(Config) when is_list(Config) -> 20000 = length(F(info_msg)), {info, joining} = qlc_SUITE:read_error_logger(), 20000 = length(F(error_msg)), - {error, joining} = qlc_SUITE:read_error_logger(), - _ = erlang:system_flag(backtrace_depth, D), + {error, joining} = qlc_SUITE:read_error_logger() + after + _ = erlang:system_flag(backtrace_depth, D) + end, qlc_SUITE:uninstall_error_logger()">>], ?line run(Config, T1), @@ -7399,70 +7401,37 @@ backward(doc) -> "OTP-6674. Join info and extra constants."; backward(suite) -> []; backward(Config) when is_list(Config) -> - case try_old_join_info(Config) of - ok -> - ok; - Reply -> - Reply - end. - --ifdef(debug). -try_old_join_info(_Config) -> + try_old_join_info(Config), ok. --else. + try_old_join_info(Config) -> - case ?t:is_release_available("r12b") of - true -> - %% Check join info for handlers of extra constants. Start R12B-0. - ?line {ok, R12} = start_node_rel(r12, r12b, slave), - File = filename("handle.erl", Config), - ?line file:write_file(File, - <<"-module(handle).\n" - "-export([create_handle/0, lookup_handle/0]).\n" - "-include_lib(\"stdlib/include/qlc.hrl\").\n" - "create_handle() ->\n" - " H1 = qlc:sort([{192.0,1,a},{192.0,2,b},{192.0,3,c}]),\n" - " qlc:q([{X, Y} || {B,X,_} <- H1,\n" - " B =:= 192.0,\n" - " {Y} <- [{0},{1},{2}],\n" - " X == Y]).\n", - "\n", - "lookup_handle() ->\n" - " E = qlc_SUITE:table([{1,a},{2,b},{3,c}], 1, [1]),\n" - " qlc:q([{X, Y} || {X,_} <- E,\n" - " {Y} <- [{0},{1},{2}],\n" - " X =:= Y]).\n">>), - ?line {ok, handle} = rpc:call(R12, compile, file, - [File, [{outdir,?privdir}]]), - ?line {module, handle} = rpc:call(R12, code, load_abs, - [filename:rootname(File)]), - ?line H = rpc:call(R12, handle, create_handle, []), - ?line {module, handle} = code:load_abs(filename:rootname(File)), - ?line {block,0, - [{match,_,_, - {call,_,_, - [{lc,_,_, - [_, - {op,_,'=:=', - {float,_,192.0}, - {call,_,{atom,_,element},[{integer,_,1},_]}}]}]}}, - _,_, - {call,_,_, - [{lc,_,_, - [_, - {op,_,'=:=',{var,_,'B'},{float,_,192.0}}, - {op,_,'==',{var,_,'X'},{var,_,'Y'}}]}]}]} - = qlc:info(H,{format,abstract_code}), - ?line [{1,1},{2,2}] = qlc:e(H), - ?line H2 = rpc:call(R12, handle, lookup_handle, []), - ?line {qlc,_,[{generate,_,{qlc,_,_,[{join,lookup}]}},_],[]} = - qlc:info(H2, {format,debug}), - ?line [{1,1},{2,2}] = qlc:e(H2), - stop_node(R12); - false -> - ?line {skipped, "No support for old node"} - end. --endif. + %% Check join info for handlers of extra constants. + File = filename:join(?datadir, "join_info_compat.erl"), + M = join_info_compat, + {ok, M} = compile:file(File, [{outdir, ?datadir}]), + {module, M} = code:load_abs(filename:rootname(File)), + H = M:create_handle(), + {block,0, + [{match,_,_, + {call,_,_, + [{lc,_,_, + [_, + {op,_,'=:=', + {float,_,192.0}, + {call,_,{atom,_,element},[{integer,_,1},_]}}]}]}}, + _,_, + {call,_,_, + [{lc,_,_, + [_, + {op,_,'=:=',{var,_,'B'},{float,_,192.0}}, + {op,_,'==',{var,_,'X'},{var,_,'Y'}}]}]}]} + = qlc:info(H,{format,abstract_code}), + [{1,1},{2,2}] = qlc:e(H), + + H2 = M:lookup_handle(), + {qlc,_,[{generate,_,{qlc,_,_,[{join,lookup}]}},_],[]} = + qlc:info(H2, {format,debug}), + [{1,1},{2,2}] = qlc:e(H2). forward(doc) -> ""; @@ -8127,27 +8096,6 @@ fail(Source) -> %% Copied from global_SUITE.erl. -start_node_rel(Name, Rel, How) -> - {Release, Compat} = case Rel of - this -> - {[this], "+R8"}; - Rel when is_atom(Rel) -> - {[{release, atom_to_list(Rel)}], ""}; - RelList -> - {RelList, ""} - end, - ?line Pa = filename:dirname(code:which(?MODULE)), - ?line Res = test_server:start_node(Name, How, - [{args, - Compat ++ - " -kernel net_setuptime 100 " - " -pa " ++ Pa}, - {erl, Release}]), - Res. - -stop_node(Node) -> - ?line ?t:stop_node(Node). - install_error_logger() -> error_logger:add_report_handler(?MODULE, self()). diff --git a/lib/stdlib/test/qlc_SUITE_data/join_info_compat.erl b/lib/stdlib/test/qlc_SUITE_data/join_info_compat.erl new file mode 100644 index 0000000000..e0db132c47 --- /dev/null +++ b/lib/stdlib/test/qlc_SUITE_data/join_info_compat.erl @@ -0,0 +1,1771 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2008-2011. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +-module(join_info_compat). + +-compile(export_all). + +create_handle() -> + H1 = qlc:sort([{192.0,1,a},{192.0,2,b},{192.0,3,c}]), + qlc:q({qlc_lc, + % fun-info: {23,109048965,'-create_handle/0-fun-23-'} + fun() -> + {qlc_v1, + % fun-info: {2,105724313,'-create_handle/0-fun-2-'} + fun(S01_0_1, RL01_0_1, Go01_0_1) -> + Fun1_0_1 = + % fun-info: {1,131900588,'-create_handle/0-fun-1-'} + fun(0, RL1_0_1, _, _, _, _, _, _, _) + when is_list(RL1_0_1) -> + lists:reverse(RL1_0_1); + (0, _, _, _, _, _, _, _, _) -> + []; + (1, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + C1_1_1, + B1, + X1) + when is_list(RL1_0_1) -> + Fun1_0_1(element(1, Go1_0_1), + [{X1,Y1}|RL1_0_1], + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + C1_1_1, + B1, + X1); + (1, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + C1_1_1, + B1, + X1) -> + [{X1,Y1}| + % fun-info: {0,27702789,'-create_handle/0-fun-0-'} + fun() -> + Fun1_0_1(element(1, + Go1_0_1), + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + C1_1_1, + B1, + X1) + end]; + (2, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + _, + B1, + X1) -> + Fun1_0_1(3, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + element(4, Go1_0_1), + B1, + X1); + (3, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + [{B1,X1,_}|C1_0_1], + _, + _) -> + Fun1_0_1(element(3, Go1_0_1), + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + C1_0_1, + B1, + X1); + (3, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + [_|C1_0_1], + _, + _) -> + Fun1_0_1(3, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + C1_0_1, + [], + []); + (3, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + [], + _, + _) -> + Fun1_0_1(element(2, Go1_0_1), + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + [], + [], + []); + (3, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + C1_1_1, + _, + _) -> + case C1_1_1() of + [{B1,X1,_}|C1_0_1] -> + Fun1_0_1(element(3, + Go1_0_1), + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + C1_0_1, + B1, + X1); + [_|C1_0_1] -> + Fun1_0_1(3, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + C1_0_1, + [], + []); + [] -> + Fun1_0_1(element(2, + Go1_0_1), + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + [], + [], + []); + E1_0_1 -> + E1_0_1 + end; + (4, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + C1_1_1, + B1, + X1) -> + if + B1 =:= 192.0 -> + Fun1_0_1(element(6, + Go1_0_1), + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + C1_1_1, + B1, + X1); + true -> + Fun1_0_1(element(5, + Go1_0_1), + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + C1_1_1, + B1, + X1) + end; + (5, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + _, + Y1, + C1_1_1, + B1, + X1) -> + Fun1_0_1(6, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + element(9, Go1_0_1), + Y1, + C1_1_1, + B1, + X1); + (6, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + [{Y1}|C1_0_1], + _, + C1_1_1, + B1, + X1) -> + Fun1_0_1(element(8, Go1_0_1), + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_0_1, + Y1, + C1_1_1, + B1, + X1); + (6, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + [_|C1_0_1], + _, + C1_1_1, + B1, + X1) -> + Fun1_0_1(6, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_0_1, + [], + C1_1_1, + B1, + X1); + (6, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + [], + _, + C1_1_1, + B1, + X1) -> + Fun1_0_1(element(7, Go1_0_1), + RL1_0_1, + Fun1_0_1, + Go1_0_1, + [], + [], + C1_1_1, + B1, + X1); + (6, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + _, + C1_1_1, + B1, + X1) -> + case C1_3_1() of + [{Y1}|C1_0_1] -> + Fun1_0_1(element(8, + Go1_0_1), + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_0_1, + Y1, + C1_1_1, + B1, + X1); + [_|C1_0_1] -> + Fun1_0_1(6, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_0_1, + [], + C1_1_1, + B1, + X1); + [] -> + Fun1_0_1(element(7, + Go1_0_1), + RL1_0_1, + Fun1_0_1, + Go1_0_1, + [], + [], + C1_1_1, + B1, + X1); + E1_0_1 -> + E1_0_1 + end; + (7, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + C1_1_1, + B1, + X1) -> + if + X1 == Y1 -> + Fun1_0_1(element(11, + Go1_0_1), + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + C1_1_1, + B1, + X1); + true -> + Fun1_0_1(element(10, + Go1_0_1), + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + C1_1_1, + B1, + X1) + end; + (8, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + _, + B1, + X1) -> + Fun1_0_1(9, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + element(14, Go1_0_1), + B1, + X1); + (9, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + _, + [[{B1,X1,_}|{Y1}]|C1_0_1], + _, + _) -> + Fun1_0_1(element(13, Go1_0_1), + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + C1_0_1, + B1, + X1); + (9, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + _, + [_|C1_0_1], + _, + _) -> + Fun1_0_1(9, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + [], + C1_0_1, + [], + []); + (9, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + _, + [], + _, + _) -> + Fun1_0_1(element(12, Go1_0_1), + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + [], + [], + [], + []); + (9, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + _, + C1_1_1, + _, + _) -> + case C1_1_1() of + [[{B1,X1,_}|{Y1}]|C1_0_1] -> + Fun1_0_1(element(13, + Go1_0_1), + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + Y1, + C1_0_1, + B1, + X1); + [_|C1_0_1] -> + Fun1_0_1(9, + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + [], + C1_0_1, + [], + []); + [] -> + Fun1_0_1(element(12, + Go1_0_1), + RL1_0_1, + Fun1_0_1, + Go1_0_1, + C1_3_1, + [], + [], + [], + []); + E1_0_1 -> + E1_0_1 + end + end, + Fun1_0_1(S01_0_1, + RL01_0_1, + Fun1_0_1, + Go01_0_1, + [], + [], + [], + [], + []) + end, + % fun-info: {3,41816426,'-create_handle/0-fun-3-'} + fun() -> + {<<$\203:8/integer-unit:1-unsigned-big, + $P:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $.:8/integer-unit:1-unsigned-big, + $x:8/integer-unit:1-unsigned-big, + $\234:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $N:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $-:8/integer-unit:1-unsigned-big, + $):8/integer-unit:1-unsigned-big, + $-:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $I:8/integer-unit:1-unsigned-big, + $M:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\n:8/integer-unit:1-unsigned-big, + $0:8/integer-unit:1-unsigned-big, + $\227:8/integer-unit:1-unsigned-big, + $%:8/integer-unit:1-unsigned-big, + $\026:8/integer-unit:1-unsigned-big, + $%:8/integer-unit:1-unsigned-big, + $r:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $0:8/integer-unit:1-unsigned-big, + $0:8/integer-unit:1-unsigned-big, + $F:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $":8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\n:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big>>, + <<$\203:8/integer-unit:1-unsigned-big, + $P:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $<:8/integer-unit:1-unsigned-big, + $x:8/integer-unit:1-unsigned-big, + $\234:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $N:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $-:8/integer-unit:1-unsigned-big, + $):8/integer-unit:1-unsigned-big, + $-:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $I:8/integer-unit:1-unsigned-big, + $M:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\n:8/integer-unit:1-unsigned-big, + $0:8/integer-unit:1-unsigned-big, + $\227:8/integer-unit:1-unsigned-big, + $%:8/integer-unit:1-unsigned-big, + $\026:8/integer-unit:1-unsigned-big, + $%:8/integer-unit:1-unsigned-big, + $r:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $0:8/integer-unit:1-unsigned-big, + $0:8/integer-unit:1-unsigned-big, + $::8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $":8/integer-unit:1-unsigned-big, + $P:8/integer-unit:1-unsigned-big, + $x:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $Y:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $9:8/integer-unit:1-unsigned-big, + $\r:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big>>, + <<$\203:8/integer-unit:1-unsigned-big, + $P:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $I:8/integer-unit:1-unsigned-big, + $x:8/integer-unit:1-unsigned-big, + $\234:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $M:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $/:8/integer-unit:1-unsigned-big, + $H:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $N:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $\006:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $e:8/integer-unit:1-unsigned-big, + $\211:8/integer-unit:1-unsigned-big, + $E:8/integer-unit:1-unsigned-big, + $\s:8/integer-unit:1-unsigned-big, + $>:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\023:8/integer-unit:1-unsigned-big, + $\210:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\232:8/integer-unit:1-unsigned-big, + $\226:8/integer-unit:1-unsigned-big, + $\223:8/integer-unit:1-unsigned-big, + $\237:8/integer-unit:1-unsigned-big, + $X:8/integer-unit:1-unsigned-big, + $\222:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\235:8/integer-unit:1-unsigned-big, + $l:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $g:8/integer-unit:1-unsigned-big, + $i:8/integer-unit:1-unsigned-big, + $d:8/integer-unit:1-unsigned-big, + $\200:8/integer-unit:1-unsigned-big, + $\001:8/integer-unit:1-unsigned-big, + $R:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\r:8/integer-unit:1-unsigned-big, + $\214:8/integer-unit:1-unsigned-big, + $\030:8/integer-unit:1-unsigned-big, + $@:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $c:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\017:8/integer-unit:1-unsigned-big, + $=:8/integer-unit:1-unsigned-big>>, + <<$\203:8/integer-unit:1-unsigned-big, + $h:8/integer-unit:1-unsigned-big, + $\003:8/integer-unit:1-unsigned-big, + $d:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\005:8/integer-unit:1-unsigned-big, + $t:8/integer-unit:1-unsigned-big, + $u:8/integer-unit:1-unsigned-big, + $p:8/integer-unit:1-unsigned-big, + $l:8/integer-unit:1-unsigned-big, + $e:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $\f:8/integer-unit:1-unsigned-big, + $l:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\001:8/integer-unit:1-unsigned-big, + $h:8/integer-unit:1-unsigned-big, + $\003:8/integer-unit:1-unsigned-big, + $d:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\003:8/integer-unit:1-unsigned-big, + $v:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $r:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $\f:8/integer-unit:1-unsigned-big, + $d:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\001:8/integer-unit:1-unsigned-big, + $Y:8/integer-unit:1-unsigned-big, + $j:8/integer-unit:1-unsigned-big>>, + <<$\203:8/integer-unit:1-unsigned-big, + $P:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $*:8/integer-unit:1-unsigned-big, + $x:8/integer-unit:1-unsigned-big, + $\234:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $M:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $/:8/integer-unit:1-unsigned-big, + $H:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\005:8/integer-unit:1-unsigned-big, + $R:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\031:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $):8/integer-unit:1-unsigned-big, + $\f:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $e:8/integer-unit:1-unsigned-big, + $\211:8/integer-unit:1-unsigned-big, + $E:8/integer-unit:1-unsigned-big, + $\s:8/integer-unit:1-unsigned-big, + $.:8/integer-unit:1-unsigned-big, + $c:8/integer-unit:1-unsigned-big, + $\004:8/integer-unit:1-unsigned-big, + $\n:8/integer-unit:1-unsigned-big, + $/:8/integer-unit:1-unsigned-big, + $\022:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\205:8/integer-unit:1-unsigned-big, + $\t:8/integer-unit:1-unsigned-big, + $\216:8/integer-unit:1-unsigned-big>>, + <<$\203:8/integer-unit:1-unsigned-big, + $P:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $j:8/integer-unit:1-unsigned-big, + $x:8/integer-unit:1-unsigned-big, + $\234:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $I:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $I:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $+:8/integer-unit:1-unsigned-big, + $N:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\f:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\024:8/integer-unit:1-unsigned-big, + $\006:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\222:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\202:8/integer-unit:1-unsigned-big, + $\234:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $D:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\034:8/integer-unit:1-unsigned-big, + $\006:8/integer-unit:1-unsigned-big, + $\006:8/integer-unit:1-unsigned-big, + $\006:8/integer-unit:1-unsigned-big, + $f:8/integer-unit:1-unsigned-big, + $\220:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $s:8/integer-unit:1-unsigned-big, + $Y:8/integer-unit:1-unsigned-big, + $b:8/integer-unit:1-unsigned-big, + $Q:8/integer-unit:1-unsigned-big, + $":8/integer-unit:1-unsigned-big, + $W:8/integer-unit:1-unsigned-big, + $\n:8/integer-unit:1-unsigned-big, + $\003:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\023:8/integer-unit:1-unsigned-big, + $\n:8/integer-unit:1-unsigned-big, + $/:8/integer-unit:1-unsigned-big, + $\002:8/integer-unit:1-unsigned-big, + $\205:8/integer-unit:1-unsigned-big, + $\027:8/integer-unit:1-unsigned-big, + $\237:8/integer-unit:1-unsigned-big, + $\205:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\227:8/integer-unit:1-unsigned-big, + $\007:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\227:8/integer-unit:1-unsigned-big, + $\021:8/integer-unit:1-unsigned-big, + $.:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\003:8/integer-unit:1-unsigned-big, + $\224:8/integer-unit:1-unsigned-big, + $\217:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\002:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\203:8/integer-unit:1-unsigned-big, + $>:8/integer-unit:1-unsigned-big, + $\034:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big>>} + end, + [{1, + 2, + 2, + {gen, + % fun-info: {4,131674517,'-create_handle/0-fun-4-'} + fun() -> + H1 + end}}, + {2,5,4,fil}, + {3, + 7, + 5, + {gen, + % fun-info: {5,108000324,'-create_handle/0-fun-5-'} + fun() -> + [{0},{1},{2}] + end}}, + {4,10,7,fil}, + {5, + 12, + 8, + {gen, + {join, + '==', + 1, + 3, + % fun-info: {9,59718458,'-create_handle/0-fun-9-'} + fun(H1_0_1) -> + F1_0_1 = + % fun-info: {7,779460,'-create_handle/0-fun-7-'} + fun(_, []) -> + []; + (F1_0_1, [O1_0_1|C1_0_1]) -> + case O1_0_1 of + {_,_,_} + when + 192.0 + =:= + element(1, O1_0_1) -> + [O1_0_1| + % fun-info: {6,23729943,'-create_handle/0-fun-6-'} + fun() -> + F1_0_1(F1_0_1, + C1_0_1) + end]; + _ -> + F1_0_1(F1_0_1, C1_0_1) + end; + (F1_0_1, C1_0_1) + when is_function(C1_0_1) -> + F1_0_1(F1_0_1, C1_0_1()); + (_, C1_0_1) -> + C1_0_1 + end, + % fun-info: {8,43652904,'-create_handle/0-fun-8-'} + fun() -> + F1_0_1(F1_0_1, H1_0_1) + end + end, + % fun-info: {13,102310144,'-create_handle/0-fun-13-'} + fun(H1_0_1) -> + F1_0_1 = + % fun-info: {11,74362432,'-create_handle/0-fun-11-'} + fun(_, []) -> + []; + (F1_0_1, [O1_0_1|C1_0_1]) -> + case O1_0_1 of + {_} -> + [O1_0_1| + % fun-info: {10,23729943,'-create_handle/0-fun-10-'} + fun() -> + F1_0_1(F1_0_1, + C1_0_1) + end]; + _ -> + F1_0_1(F1_0_1, C1_0_1) + end; + (F1_0_1, C1_0_1) + when is_function(C1_0_1) -> + F1_0_1(F1_0_1, C1_0_1()); + (_, C1_0_1) -> + C1_0_1 + end, + % fun-info: {12,43652904,'-create_handle/0-fun-12-'} + fun() -> + F1_0_1(F1_0_1, H1_0_1) + end + end, + % fun-info: {14,17838355,'-create_handle/0-fun-14-'} + fun() -> + {[{1,[192.0]}],[],[]} + end}}}], + % fun-info: {22,31304647,'-create_handle/0-fun-22-'} + fun(join) -> + {[[{1,"\002"},{3,"\001"}]],[]}; + (size) -> + % fun-info: {15,31963143,'-create_handle/0-fun-15-'} + fun(0) -> + 2; + (1) -> + 3; + (3) -> + 1; + (_) -> + undefined + end; + (template) -> + % fun-info: {16,113413274,'-create_handle/0-fun-16-'} + fun({1,2}, '=:=') -> + "\001"; + ({1,2}, '==') -> + "\001\002"; + ({3,1}, '=:=') -> + "\002"; + ({3,1}, '==') -> + "\001\002"; + (_, _) -> + [] + end; + (constants) -> + % fun-info: {18,52148739,'-create_handle/0-fun-18-'} + fun(1) -> + % fun-info: {17,5864387,'-create_handle/0-fun-17-'} + fun(1) -> + {values,[192.0],{some,[2]}}; + (_) -> + false + end; + (_) -> + no_column_fun + end; + (n_leading_constant_columns) -> + % fun-info: {19,82183172,'-create_handle/0-fun-19-'} + fun(1) -> + 1; + (_) -> + 0 + end; + (constant_columns) -> + % fun-info: {20,80910005,'-create_handle/0-fun-20-'} + fun(1) -> + "\001"; + (_) -> + [] + end; + (match_specs) -> + % fun-info: {21,91764346,'-create_handle/0-fun-21-'} + fun(1) -> + {[{{'$1','$2','_'}, + [{'=:=','$1',192.0}], + ['$_']}], + "\002"}; + (_) -> + undefined + end; + (_) -> + undefined + end} + end, + undefined}). + +lookup_handle() -> + E = qlc_SUITE:table([{1,a},{2,b},{3,c}], 1, [1]), + qlc:q({qlc_lc, + % fun-info: {46,120768015,'-lookup_handle/0-fun-22-'} + fun() -> + {qlc_v1, + % fun-info: {26,82970908,'-lookup_handle/0-fun-2-'} + fun(S02_0_1, RL02_0_1, Go02_0_1) -> + Fun2_0_1 = + % fun-info: {25,75235357,'-lookup_handle/0-fun-1-'} + fun(0, RL2_0_1, _, _, _, _, _, _) + when is_list(RL2_0_1) -> + lists:reverse(RL2_0_1); + (0, _, _, _, _, _, _, _) -> + []; + (1, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + C2_1_1, + X2) + when is_list(RL2_0_1) -> + Fun2_0_1(element(1, Go2_0_1), + [{X2,Y2}|RL2_0_1], + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + C2_1_1, + X2); + (1, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + C2_1_1, + X2) -> + [{X2,Y2}| + % fun-info: {24,124255471,'-lookup_handle/0-fun-0-'} + fun() -> + Fun2_0_1(element(1, + Go2_0_1), + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + C2_1_1, + X2) + end]; + (2, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + _, + X2) -> + Fun2_0_1(3, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + element(4, Go2_0_1), + X2); + (3, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + [{X2,_}|C2_0_1], + _) -> + Fun2_0_1(element(3, Go2_0_1), + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + C2_0_1, + X2); + (3, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + [_|C2_0_1], + _) -> + Fun2_0_1(3, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + C2_0_1, + []); + (3, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + [], + _) -> + Fun2_0_1(element(2, Go2_0_1), + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + [], + []); + (3, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + C2_1_1, + _) -> + case C2_1_1() of + [{X2,_}|C2_0_1] -> + Fun2_0_1(element(3, + Go2_0_1), + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + C2_0_1, + X2); + [_|C2_0_1] -> + Fun2_0_1(3, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + C2_0_1, + []); + [] -> + Fun2_0_1(element(2, + Go2_0_1), + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + [], + []); + E2_0_1 -> + E2_0_1 + end; + (4, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + _, + Y2, + C2_1_1, + X2) -> + Fun2_0_1(5, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + element(7, Go2_0_1), + Y2, + C2_1_1, + X2); + (5, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + [{Y2}|C2_0_1], + _, + C2_1_1, + X2) -> + Fun2_0_1(element(6, Go2_0_1), + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_0_1, + Y2, + C2_1_1, + X2); + (5, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + [_|C2_0_1], + _, + C2_1_1, + X2) -> + Fun2_0_1(5, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_0_1, + [], + C2_1_1, + X2); + (5, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + [], + _, + C2_1_1, + X2) -> + Fun2_0_1(element(5, Go2_0_1), + RL2_0_1, + Fun2_0_1, + Go2_0_1, + [], + [], + C2_1_1, + X2); + (5, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + _, + C2_1_1, + X2) -> + case C2_2_1() of + [{Y2}|C2_0_1] -> + Fun2_0_1(element(6, + Go2_0_1), + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_0_1, + Y2, + C2_1_1, + X2); + [_|C2_0_1] -> + Fun2_0_1(5, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_0_1, + [], + C2_1_1, + X2); + [] -> + Fun2_0_1(element(5, + Go2_0_1), + RL2_0_1, + Fun2_0_1, + Go2_0_1, + [], + [], + C2_1_1, + X2); + E2_0_1 -> + E2_0_1 + end; + (6, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + C2_1_1, + X2) -> + if + X2 =:= Y2 -> + Fun2_0_1(element(9, + Go2_0_1), + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + C2_1_1, + X2); + true -> + Fun2_0_1(element(8, + Go2_0_1), + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + C2_1_1, + X2) + end; + (7, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + _, + X2) -> + Fun2_0_1(8, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + element(12, Go2_0_1), + X2); + (8, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + _, + [[{X2,_}|{Y2}]|C2_0_1], + _) -> + Fun2_0_1(element(11, Go2_0_1), + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + C2_0_1, + X2); + (8, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + _, + [_|C2_0_1], + _) -> + Fun2_0_1(8, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + [], + C2_0_1, + []); + (8, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + _, + [], + _) -> + Fun2_0_1(element(10, Go2_0_1), + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + [], + [], + []); + (8, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + _, + C2_1_1, + _) -> + case C2_1_1() of + [[{X2,_}|{Y2}]|C2_0_1] -> + Fun2_0_1(element(11, + Go2_0_1), + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + Y2, + C2_0_1, + X2); + [_|C2_0_1] -> + Fun2_0_1(8, + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + [], + C2_0_1, + []); + [] -> + Fun2_0_1(element(10, + Go2_0_1), + RL2_0_1, + Fun2_0_1, + Go2_0_1, + C2_2_1, + [], + [], + []); + E2_0_1 -> + E2_0_1 + end + end, + Fun2_0_1(S02_0_1, + RL02_0_1, + Fun2_0_1, + Go02_0_1, + [], + [], + [], + []) + end, + % fun-info: {27,111349661,'-lookup_handle/0-fun-3-'} + fun() -> + {<<$\203:8/integer-unit:1-unsigned-big, + $P:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $.:8/integer-unit:1-unsigned-big, + $x:8/integer-unit:1-unsigned-big, + $\234:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $N:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $-:8/integer-unit:1-unsigned-big, + $):8/integer-unit:1-unsigned-big, + $-:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $I:8/integer-unit:1-unsigned-big, + $M:8/integer-unit:1-unsigned-big, + $\024:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\n:8/integer-unit:1-unsigned-big, + $0:8/integer-unit:1-unsigned-big, + $\227:8/integer-unit:1-unsigned-big, + $%:8/integer-unit:1-unsigned-big, + $\026:8/integer-unit:1-unsigned-big, + $%:8/integer-unit:1-unsigned-big, + $\n:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $0:8/integer-unit:1-unsigned-big, + $0:8/integer-unit:1-unsigned-big, + $F:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $":8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\206:8/integer-unit:1-unsigned-big, + $\n:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big>>, + <<$\203:8/integer-unit:1-unsigned-big, + $P:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $.:8/integer-unit:1-unsigned-big, + $x:8/integer-unit:1-unsigned-big, + $\234:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $N:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $-:8/integer-unit:1-unsigned-big, + $):8/integer-unit:1-unsigned-big, + $-:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $I:8/integer-unit:1-unsigned-big, + $M:8/integer-unit:1-unsigned-big, + $\024:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\n:8/integer-unit:1-unsigned-big, + $0:8/integer-unit:1-unsigned-big, + $\227:8/integer-unit:1-unsigned-big, + $%:8/integer-unit:1-unsigned-big, + $\026:8/integer-unit:1-unsigned-big, + $%:8/integer-unit:1-unsigned-big, + $\n:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $0:8/integer-unit:1-unsigned-big, + $0:8/integer-unit:1-unsigned-big, + $F:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\222:8/integer-unit:1-unsigned-big, + $\n:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big>>, + <<$\203:8/integer-unit:1-unsigned-big, + $h:8/integer-unit:1-unsigned-big, + $\003:8/integer-unit:1-unsigned-big, + $d:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\005:8/integer-unit:1-unsigned-big, + $t:8/integer-unit:1-unsigned-big, + $u:8/integer-unit:1-unsigned-big, + $p:8/integer-unit:1-unsigned-big, + $l:8/integer-unit:1-unsigned-big, + $e:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $\022:8/integer-unit:1-unsigned-big, + $l:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\001:8/integer-unit:1-unsigned-big, + $h:8/integer-unit:1-unsigned-big, + $\003:8/integer-unit:1-unsigned-big, + $d:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\003:8/integer-unit:1-unsigned-big, + $v:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $r:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $\022:8/integer-unit:1-unsigned-big, + $d:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\001:8/integer-unit:1-unsigned-big, + $Y:8/integer-unit:1-unsigned-big, + $j:8/integer-unit:1-unsigned-big>>, + <<$\203:8/integer-unit:1-unsigned-big, + $P:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $+:8/integer-unit:1-unsigned-big, + $x:8/integer-unit:1-unsigned-big, + $\234:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $M:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $/:8/integer-unit:1-unsigned-big, + $H:8/integer-unit:1-unsigned-big, + $\024:8/integer-unit:1-unsigned-big, + $N:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $\006:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $e:8/integer-unit:1-unsigned-big, + $\211:8/integer-unit:1-unsigned-big, + $E:8/integer-unit:1-unsigned-big, + $\s:8/integer-unit:1-unsigned-big, + $>:8/integer-unit:1-unsigned-big, + $c:8/integer-unit:1-unsigned-big, + $\004:8/integer-unit:1-unsigned-big, + $\n:8/integer-unit:1-unsigned-big, + $/:8/integer-unit:1-unsigned-big, + $\022:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\227:8/integer-unit:1-unsigned-big, + $\t:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big>>, + <<$\203:8/integer-unit:1-unsigned-big, + $P:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\\:8/integer-unit:1-unsigned-big, + $x:8/integer-unit:1-unsigned-big, + $\234:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $I:8/integer-unit:1-unsigned-big, + $a:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $I:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $+:8/integer-unit:1-unsigned-big, + $N:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\f:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\024:8/integer-unit:1-unsigned-big, + $\006:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\222:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\202:8/integer-unit:1-unsigned-big, + $\234:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $D:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\034:8/integer-unit:1-unsigned-big, + $\006:8/integer-unit:1-unsigned-big, + $\006:8/integer-unit:1-unsigned-big, + $\006:8/integer-unit:1-unsigned-big, + $&:8/integer-unit:1-unsigned-big, + $\220:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $s:8/integer-unit:1-unsigned-big, + $Y:8/integer-unit:1-unsigned-big, + $b:8/integer-unit:1-unsigned-big, + $Q:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $`:8/integer-unit:1-unsigned-big, + $\n:8/integer-unit:1-unsigned-big, + $\003:8/integer-unit:1-unsigned-big, + $c:8/integer-unit:1-unsigned-big, + $\004:8/integer-unit:1-unsigned-big, + $\n:8/integer-unit:1-unsigned-big, + $/:8/integer-unit:1-unsigned-big, + $>:8/integer-unit:1-unsigned-big, + $\v:8/integer-unit:1-unsigned-big, + $I:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\020:8/integer-unit:1-unsigned-big, + $H:8/integer-unit:1-unsigned-big, + $5:8/integer-unit:1-unsigned-big, + $#:8/integer-unit:1-unsigned-big, + $\\:8/integer-unit:1-unsigned-big, + $^:8/integer-unit:1-unsigned-big, + $\b:8/integer-unit:1-unsigned-big, + $(:8/integer-unit:1-unsigned-big, + $\037:8/integer-unit:1-unsigned-big, + $\231:8/integer-unit:1-unsigned-big, + $\005:8/integer-unit:1-unsigned-big, + $\000:8/integer-unit:1-unsigned-big, + $\024:8/integer-unit:1-unsigned-big, + $�:8/integer-unit:1-unsigned-big, + $\031:8/integer-unit:1-unsigned-big, + $M:8/integer-unit:1-unsigned-big>>} + end, + [{1, + 2, + 2, + {gen, + % fun-info: {28,75197307,'-lookup_handle/0-fun-4-'} + fun() -> + E + end}}, + {2, + 5, + 4, + {gen, + % fun-info: {29,86826511,'-lookup_handle/0-fun-5-'} + fun() -> + [{0},{1},{2}] + end}}, + {3,8,6,fil}, + {4, + 10, + 7, + {gen, + {join, + '==', + 1, + 2, + % fun-info: {33,129609919,'-lookup_handle/0-fun-9-'} + fun(H2_0_1) -> + F2_0_1 = + % fun-info: {31,45768082,'-lookup_handle/0-fun-7-'} + fun(_, []) -> + []; + (F2_0_1, [O2_0_1|C2_0_1]) -> + case O2_0_1 of + {_,_} -> + [O2_0_1| + % fun-info: {30,28136696,'-lookup_handle/0-fun-6-'} + fun() -> + F2_0_1(F2_0_1, + C2_0_1) + end]; + _ -> + F2_0_1(F2_0_1, C2_0_1) + end; + (F2_0_1, C2_0_1) + when is_function(C2_0_1) -> + F2_0_1(F2_0_1, C2_0_1()); + (_, C2_0_1) -> + C2_0_1 + end, + % fun-info: {32,48059625,'-lookup_handle/0-fun-8-'} + fun() -> + F2_0_1(F2_0_1, H2_0_1) + end + end, + % fun-info: {37,63676968,'-lookup_handle/0-fun-13-'} + fun(H2_0_1) -> + F2_0_1 = + % fun-info: {35,129320532,'-lookup_handle/0-fun-11-'} + fun(_, []) -> + []; + (F2_0_1, [O2_0_1|C2_0_1]) -> + case O2_0_1 of + {_} -> + [O2_0_1| + % fun-info: {34,28136696,'-lookup_handle/0-fun-10-'} + fun() -> + F2_0_1(F2_0_1, + C2_0_1) + end]; + _ -> + F2_0_1(F2_0_1, C2_0_1) + end; + (F2_0_1, C2_0_1) + when is_function(C2_0_1) -> + F2_0_1(F2_0_1, C2_0_1()); + (_, C2_0_1) -> + C2_0_1 + end, + % fun-info: {36,48059625,'-lookup_handle/0-fun-12-'} + fun() -> + F2_0_1(F2_0_1, H2_0_1) + end + end, + % fun-info: {38,3236543,'-lookup_handle/0-fun-14-'} + fun() -> + {[],[],[]} + end}}}], + % fun-info: {45,56361026,'-lookup_handle/0-fun-21-'} + fun(join) -> + [[{1,"\001"},{2,"\001"}]]; + (size) -> + % fun-info: {39,40607542,'-lookup_handle/0-fun-15-'} + fun(0) -> + 2; + (1) -> + 2; + (2) -> + 1; + (_) -> + undefined + end; + (template) -> + % fun-info: {40,34907048,'-lookup_handle/0-fun-16-'} + fun({1,1}, _) -> + "\001\002"; + ({2,1}, _) -> + "\001\002"; + (_, _) -> + [] + end; + (constants) -> + % fun-info: {41,11686091,'-lookup_handle/0-fun-17-'} + fun(_) -> + no_column_fun + end; + (n_leading_constant_columns) -> + % fun-info: {42,21492441,'-lookup_handle/0-fun-18-'} + fun(_) -> + 0 + end; + (constant_columns) -> + % fun-info: {43,55297177,'-lookup_handle/0-fun-19-'} + fun(_) -> + [] + end; + (match_specs) -> + % fun-info: {44,55081557,'-lookup_handle/0-fun-20-'} + fun(_) -> + undefined + end; + (_) -> + undefined + end} + end, + undefined}). diff --git a/lib/stdlib/test/stdlib_SUITE.erl b/lib/stdlib/test/stdlib_SUITE.erl index 0cca030b3d..8a2cb5ea6b 100644 --- a/lib/stdlib/test/stdlib_SUITE.erl +++ b/lib/stdlib/test/stdlib_SUITE.erl @@ -33,8 +33,7 @@ -export([init_per_testcase/2, end_per_testcase/2]). % Test cases must be exported. --export([app_test/1]). --define(cases, [app_test]). +-export([app_test/1, appup_test/1]). %% %% all/1 @@ -42,7 +41,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> - [app_test]. + [app_test, appup_test]. groups() -> []. @@ -79,3 +78,61 @@ app_test(Config) when is_list(Config) -> ?t:app_test(stdlib), ok. +%% Test that appup allows upgrade from/downgrade to a maximum of two +%% major releases back. +appup_test(_Config) -> + application:load(stdlib), + {_,_,Vsn} = lists:keyfind(stdlib,1,application:loaded_applications()), + AppupFile = filename:join([code:lib_dir(stdlib),ebin,"stdlib.appup"]), + {ok,[{Vsn,UpFrom,DownTo}=AppupScript]} = file:consult(AppupFile), + ct:log("~p~n",[AppupScript]), + {OkVsns,NokVsns} = create_test_vsns(Vsn), + check_appup(OkVsns,UpFrom,{ok,[restart_new_emulator]}), + check_appup(OkVsns,DownTo,{ok,[restart_new_emulator]}), + check_appup(NokVsns,UpFrom,error), + check_appup(NokVsns,DownTo,error), + ok. + +create_test_vsns(Current) -> + [XStr,YStr|Rest] = string:tokens(Current,"."), + X = list_to_integer(XStr), + Y = list_to_integer(YStr), + SecondMajor = vsn(X,Y-2), + SecondMinor = SecondMajor ++ ".1.3", + FirstMajor = vsn(X,Y-1), + FirstMinor = FirstMajor ++ ".57", + ThisMajor = vsn(X,Y), + This = + case Rest of + [] -> + []; + ["1"] -> + [ThisMajor]; + _ -> + ThisMinor = ThisMajor ++ ".1", + [ThisMajor,ThisMinor] + end, + OkVsns = This ++ [FirstMajor, FirstMinor, SecondMajor, SecondMinor], + + ThirdMajor = vsn(X,Y-3), + ThirdMinor = ThirdMajor ++ ".10.12", + Illegal = ThisMajor ++ ",1", + Newer1Major = vsn(X,Y+1), + Newer1Minor = Newer1Major ++ ".1", + Newer2Major = ThisMajor ++ "1", + NokVsns = [ThirdMajor,ThirdMinor, + Illegal, + Newer1Major,Newer1Minor, + Newer2Major], + {OkVsns,NokVsns}. + +vsn(X,Y) -> + integer_to_list(X) ++ "." ++ integer_to_list(Y). + +check_appup([Vsn|Vsns],Instrs,Expected) -> + case systools_relup:appup_search_for_version(Vsn, Instrs) of + Expected -> check_appup(Vsns,Instrs,Expected); + Other -> ct:fail({unexpected_result_for_vsn,Vsn,Other}) + end; +check_appup([],_,_) -> + ok. diff --git a/lib/stdlib/test/supervisor_SUITE.erl b/lib/stdlib/test/supervisor_SUITE.erl index d3d140abbc..fa6faa66f2 100644 --- a/lib/stdlib/test/supervisor_SUITE.erl +++ b/lib/stdlib/test/supervisor_SUITE.erl @@ -158,29 +158,23 @@ get_child_counts(Supervisor) -> %%------------------------------------------------------------------------- %% Test cases starts here. -%%------------------------------------------------------------------------- -sup_start_normal(doc) -> - ["Tests that the supervisor process starts correctly and that it " - "can be terminated gracefully."]; -sup_start_normal(suite) -> []; +%% ------------------------------------------------------------------------- +%% Tests that the supervisor process starts correctly and that it can +%% be terminated gracefully. sup_start_normal(Config) when is_list(Config) -> process_flag(trap_exit, true), {ok, Pid} = start_link({ok, {{one_for_one, 2, 3600}, []}}), terminate(Pid, shutdown). %%------------------------------------------------------------------------- -sup_start_ignore_init(doc) -> - ["Tests what happens if init-callback returns ignore"]; -sup_start_ignore_init(suite) -> []; +%% Tests what happens if init-callback returns ignore. sup_start_ignore_init(Config) when is_list(Config) -> process_flag(trap_exit, true), ignore = start_link(ignore), check_exit_reason(normal). %%------------------------------------------------------------------------- -sup_start_ignore_child(doc) -> - ["Tests what happens if init-callback returns ignore"]; -sup_start_ignore_child(suite) -> []; +%% Tests what happens if init-callback returns ignore. sup_start_ignore_child(Config) when is_list(Config) -> process_flag(trap_exit, true), {ok, _Pid} = start_link({ok, {{one_for_one, 2, 3600}, []}}), @@ -197,30 +191,22 @@ sup_start_ignore_child(Config) when is_list(Config) -> [2,1,0,2] = get_child_counts(sup_test). %%------------------------------------------------------------------------- -sup_start_error_return(doc) -> - ["Tests what happens if init-callback returns a invalid value"]; -sup_start_error_return(suite) -> []; +%% Tests what happens if init-callback returns a invalid value. sup_start_error_return(Config) when is_list(Config) -> process_flag(trap_exit, true), {error, Term} = start_link(invalid), check_exit_reason(Term). %%------------------------------------------------------------------------- -sup_start_fail(doc) -> - ["Tests what happens if init-callback fails"]; -sup_start_fail(suite) -> []; +%% Tests what happens if init-callback fails. sup_start_fail(Config) when is_list(Config) -> process_flag(trap_exit, true), {error, Term} = start_link(fail), check_exit_reason(Term). %%------------------------------------------------------------------------- - -sup_stop_infinity(doc) -> - ["See sup_stop/1 when Shutdown = infinity, this walue is allowed " - "for children of type supervisor _AND_ worker"]; -sup_stop_infinity(suite) -> []; - +%% See sup_stop/1 when Shutdown = infinity, this walue is allowed for +%% children of type supervisor _AND_ worker. sup_stop_infinity(Config) when is_list(Config) -> process_flag(trap_exit, true), {ok, Pid} = start_link({ok, {{one_for_one, 2, 3600}, []}}), @@ -238,11 +224,7 @@ sup_stop_infinity(Config) when is_list(Config) -> check_exit_reason(CPid2, shutdown). %%------------------------------------------------------------------------- - -sup_stop_timeout(doc) -> - ["See sup_stop/1 when Shutdown = 1000"]; -sup_stop_timeout(suite) -> []; - +%% See sup_stop/1 when Shutdown = 1000 sup_stop_timeout(Config) when is_list(Config) -> process_flag(trap_exit, true), {ok, Pid} = start_link({ok, {{one_for_one, 2, 3600}, []}}), @@ -264,10 +246,7 @@ sup_stop_timeout(Config) when is_list(Config) -> %%------------------------------------------------------------------------- -sup_stop_brutal_kill(doc) -> - ["See sup_stop/1 when Shutdown = brutal_kill"]; -sup_stop_brutal_kill(suite) -> []; - +%% See sup_stop/1 when Shutdown = brutal_kill sup_stop_brutal_kill(Config) when is_list(Config) -> process_flag(trap_exit, true), {ok, Pid} = start_link({ok, {{one_for_one, 2, 3600}, []}}), @@ -286,14 +265,10 @@ sup_stop_brutal_kill(Config) when is_list(Config) -> check_exit_reason(CPid2, killed). %%------------------------------------------------------------------------- -extra_return(doc) -> - ["The start function provided to start a child may " - "return {ok, Pid} or {ok, Pid, Info}, if it returns " - "the later check that the supervisor ignores the Info, " - "and includes it unchanged in return from start_child/2 " - "and restart_child/2"]; -extra_return(suite) -> []; - +%% The start function provided to start a child may return {ok, Pid} +%% or {ok, Pid, Info}, if it returns the latter check that the +%% supervisor ignores the Info, and includes it unchanged in return +%% from start_child/2 and restart_child/2. extra_return(Config) when is_list(Config) -> process_flag(trap_exit, true), Child = {child1, {supervisor_1, start_child, [extra_return]}, @@ -333,12 +308,10 @@ extra_return(Config) when is_list(Config) -> ok. %%------------------------------------------------------------------------- -child_adm(doc)-> - ["Test API functions start_child/2, terminate_child/2, delete_child/2 " - "restart_child/2, which_children/1, count_children/1. Only correct " - "childspecs are used, handling of incorrect childspecs is tested in " - "child_specs/1"]; -child_adm(suite) -> []; +%% Test API functions start_child/2, terminate_child/2, delete_child/2 +%% restart_child/2, which_children/1, count_children/1. Only correct +%% childspecs are used, handling of incorrect childspecs is tested in +%% child_specs/1. child_adm(Config) when is_list(Config) -> process_flag(trap_exit, true), Child = {child1, {supervisor_1, start_child, []}, permanent, 1000, @@ -402,11 +375,9 @@ child_adm(Config) when is_list(Config) -> = (catch supervisor:count_children(foo)), ok. %%------------------------------------------------------------------------- -child_adm_simple(doc) -> - ["The API functions terminate_child/2, delete_child/2 " - "restart_child/2 are not valid for a simple_one_for_one supervisor " - "check that the correct error message is returned."]; -child_adm_simple(suite) -> []; +%% The API functions terminate_child/2, delete_child/2 restart_child/2 +%% are not valid for a simple_one_for_one supervisor check that the +%% correct error message is returned. child_adm_simple(Config) when is_list(Config) -> Child = {child, {supervisor_1, start_child, []}, permanent, 1000, worker, []}, @@ -454,9 +425,7 @@ child_adm_simple(Config) when is_list(Config) -> ok. %%------------------------------------------------------------------------- -child_specs(doc) -> - ["Tests child specs, invalid formats should be rejected."]; -child_specs(suite) -> []; +%% Tests child specs, invalid formats should be rejected. child_specs(Config) when is_list(Config) -> process_flag(trap_exit, true), {ok, _Pid} = start_link({ok, {{one_for_one, 2, 3600}, []}}), @@ -507,9 +476,7 @@ child_specs(Config) when is_list(Config) -> ok. %%------------------------------------------------------------------------- -permanent_normal(doc) -> - ["A permanent child should always be restarted"]; -permanent_normal(suite) -> []; +%% A permanent child should always be restarted. permanent_normal(Config) when is_list(Config) -> {ok, SupPid} = start_link({ok, {{one_for_one, 2, 3600}, []}}), Child1 = {child1, {supervisor_1, start_child, []}, permanent, 1000, @@ -529,10 +496,8 @@ permanent_normal(Config) when is_list(Config) -> [1,1,0,1] = get_child_counts(sup_test). %%------------------------------------------------------------------------- -transient_normal(doc) -> - ["A transient child should not be restarted if it exits with " - "reason normal"]; -transient_normal(suite) -> []; +%% A transient child should not be restarted if it exits with reason +%% normal. transient_normal(Config) when is_list(Config) -> {ok, SupPid} = start_link({ok, {{one_for_one, 2, 3600}, []}}), Child1 = {child1, {supervisor_1, start_child, []}, transient, 1000, @@ -546,9 +511,7 @@ transient_normal(Config) when is_list(Config) -> [1,0,0,1] = get_child_counts(sup_test). %%------------------------------------------------------------------------- -temporary_normal(doc) -> - ["A temporary process should never be restarted"]; -temporary_normal(suite) -> []; +%% A temporary process should never be restarted. temporary_normal(Config) when is_list(Config) -> {ok, SupPid} = start_link({ok, {{one_for_one, 2, 3600}, []}}), Child1 = {child1, {supervisor_1, start_child, []}, temporary, 1000, @@ -562,9 +525,7 @@ temporary_normal(Config) when is_list(Config) -> [0,0,0,0] = get_child_counts(sup_test). %%------------------------------------------------------------------------- -permanent_shutdown(doc) -> - ["A permanent child should always be restarted"]; -permanent_shutdown(suite) -> []; +%% A permanent child should always be restarted. permanent_shutdown(Config) when is_list(Config) -> {ok, SupPid} = start_link({ok, {{one_for_one, 2, 3600}, []}}), Child1 = {child1, {supervisor_1, start_child, []}, permanent, 1000, @@ -596,10 +557,8 @@ permanent_shutdown(Config) when is_list(Config) -> [1,1,0,1] = get_child_counts(sup_test). %%------------------------------------------------------------------------- -transient_shutdown(doc) -> - ["A transient child should not be restarted if it exits with " - "reason shutdown or {shutdown,Term}"]; -transient_shutdown(suite) -> []; +%% A transient child should not be restarted if it exits with reason +%% shutdown or {shutdown,Term}. transient_shutdown(Config) when is_list(Config) -> {ok, SupPid} = start_link({ok, {{one_for_one, 2, 3600}, []}}), Child1 = {child1, {supervisor_1, start_child, []}, transient, 1000, @@ -620,9 +579,7 @@ transient_shutdown(Config) when is_list(Config) -> [1,0,0,1] = get_child_counts(sup_test). %%------------------------------------------------------------------------- -temporary_shutdown(doc) -> - ["A temporary process should never be restarted"]; -temporary_shutdown(suite) -> []; +%% A temporary process should never be restarted. temporary_shutdown(Config) when is_list(Config) -> {ok, SupPid} = start_link({ok, {{one_for_one, 2, 3600}, []}}), Child1 = {child1, {supervisor_1, start_child, []}, temporary, 1000, @@ -643,9 +600,7 @@ temporary_shutdown(Config) when is_list(Config) -> [0,0,0,0] = get_child_counts(sup_test). %%------------------------------------------------------------------------- -permanent_abnormal(doc) -> - ["A permanent child should always be restarted"]; -permanent_abnormal(suite) -> []; +%% A permanent child should always be restarted. permanent_abnormal(Config) when is_list(Config) -> {ok, SupPid} = start_link({ok, {{one_for_one, 2, 3600}, []}}), Child1 = {child1, {supervisor_1, start_child, []}, permanent, 1000, @@ -664,10 +619,7 @@ permanent_abnormal(Config) when is_list(Config) -> [1,1,0,1] = get_child_counts(sup_test). %%------------------------------------------------------------------------- -transient_abnormal(doc) -> - ["A transient child should be restarted if it exits with " - "reason abnormal"]; -transient_abnormal(suite) -> []; +%% A transient child should be restarted if it exits with reason abnormal. transient_abnormal(Config) when is_list(Config) -> {ok, SupPid} = start_link({ok, {{one_for_one, 2, 3600}, []}}), Child1 = {child1, {supervisor_1, start_child, []}, transient, 1000, @@ -686,9 +638,7 @@ transient_abnormal(Config) when is_list(Config) -> [1,1,0,1] = get_child_counts(sup_test). %%------------------------------------------------------------------------- -temporary_abnormal(doc) -> - ["A temporary process should never be restarted"]; -temporary_abnormal(suite) -> []; +%% A temporary process should never be restarted. temporary_abnormal(Config) when is_list(Config) -> {ok, SupPid} = start_link({ok, {{one_for_one, 2, 3600}, []}}), Child1 = {child1, {supervisor_1, start_child, []}, temporary, 1000, @@ -701,11 +651,9 @@ temporary_abnormal(Config) when is_list(Config) -> [0,0,0,0] = get_child_counts(sup_test). %%------------------------------------------------------------------------- -temporary_bystander(doc) -> - ["A temporary process killed as part of a rest_for_one or one_for_all " - "restart strategy should not be restarted given its args are not " - " saved. Otherwise the supervisor hits its limit and crashes."]; -temporary_bystander(suite) -> []; +%% A temporary process killed as part of a rest_for_one or one_for_all +%% restart strategy should not be restarted given its args are not +%% saved. Otherwise the supervisor hits its limit and crashes. temporary_bystander(_Config) -> Child1 = {child1, {supervisor_1, start_child, []}, permanent, 100, worker, []}, @@ -732,9 +680,7 @@ temporary_bystander(_Config) -> [{child1, _, _, _}] = supervisor:which_children(SupPid2). %%------------------------------------------------------------------------- -one_for_one(doc) -> - ["Test the one_for_one base case."]; -one_for_one(suite) -> []; +%% Test the one_for_one base case. one_for_one(Config) when is_list(Config) -> process_flag(trap_exit, true), Child1 = {child1, {supervisor_1, start_child, []}, permanent, 1000, @@ -764,9 +710,7 @@ one_for_one(Config) when is_list(Config) -> check_exit([SupPid]). %%------------------------------------------------------------------------- -one_for_one_escalation(doc) -> - ["Test restart escalation on a one_for_one supervisor."]; -one_for_one_escalation(suite) -> []; +%% Test restart escalation on a one_for_one supervisor. one_for_one_escalation(Config) when is_list(Config) -> process_flag(trap_exit, true), @@ -786,9 +730,7 @@ one_for_one_escalation(Config) when is_list(Config) -> %%------------------------------------------------------------------------- -one_for_all(doc) -> - ["Test the one_for_all base case."]; -one_for_all(suite) -> []; +%% Test the one_for_all base case. one_for_all(Config) when is_list(Config) -> process_flag(trap_exit, true), @@ -824,9 +766,7 @@ one_for_all(Config) when is_list(Config) -> %%------------------------------------------------------------------------- -one_for_all_escalation(doc) -> - ["Test restart escalation on a one_for_all supervisor."]; -one_for_all_escalation(suite) -> []; +%% Test restart escalation on a one_for_all supervisor. one_for_all_escalation(Config) when is_list(Config) -> process_flag(trap_exit, true), @@ -845,9 +785,7 @@ one_for_all_escalation(Config) when is_list(Config) -> %%------------------------------------------------------------------------- -simple_one_for_one(doc) -> - ["Test the simple_one_for_one base case."]; -simple_one_for_one(suite) -> []; +%% Test the simple_one_for_one base case. simple_one_for_one(Config) when is_list(Config) -> process_flag(trap_exit, true), Child = {child, {supervisor_1, start_child, []}, permanent, 1000, @@ -878,10 +816,8 @@ simple_one_for_one(Config) when is_list(Config) -> %%------------------------------------------------------------------------- -simple_one_for_one_shutdown(doc) -> - ["Test simple_one_for_one children shutdown accordingly to the " - "supervisor's shutdown strategy."]; -simple_one_for_one_shutdown(suite) -> []; +%% Test simple_one_for_one children shutdown accordingly to the +%% supervisor's shutdown strategy. simple_one_for_one_shutdown(Config) when is_list(Config) -> process_flag(trap_exit, true), ShutdownTime = 1000, @@ -909,10 +845,8 @@ simple_one_for_one_shutdown(Config) when is_list(Config) -> %%------------------------------------------------------------------------- -simple_one_for_one_extra(doc) -> - ["Tests automatic restart of children " - "who's start function return extra info."]; -simple_one_for_one_extra(suite) -> []; +%% Tests automatic restart of children who's start function return +%% extra info. simple_one_for_one_extra(Config) when is_list(Config) -> process_flag(trap_exit, true), Child = {child, {supervisor_1, start_child, [extra_info]}, @@ -937,9 +871,7 @@ simple_one_for_one_extra(Config) when is_list(Config) -> check_exit([SupPid]). %%------------------------------------------------------------------------- -simple_one_for_one_escalation(doc) -> - ["Test restart escalation on a simple_one_for_one supervisor."]; -simple_one_for_one_escalation(suite) -> []; +%% Test restart escalation on a simple_one_for_one supervisor. simple_one_for_one_escalation(Config) when is_list(Config) -> process_flag(trap_exit, true), Child = {child, {supervisor_1, start_child, []}, permanent, 1000, @@ -954,9 +886,7 @@ simple_one_for_one_escalation(Config) when is_list(Config) -> check_exit([SupPid, CPid2]). %%------------------------------------------------------------------------- -rest_for_one(doc) -> - ["Test the rest_for_one base case."]; -rest_for_one(suite) -> []; +%% Test the rest_for_one base case. rest_for_one(Config) when is_list(Config) -> process_flag(trap_exit, true), Child1 = {child1, {supervisor_1, start_child, []}, permanent, 1000, @@ -1004,9 +934,7 @@ rest_for_one(Config) when is_list(Config) -> check_exit([SupPid]). %%------------------------------------------------------------------------- -rest_for_one_escalation(doc) -> - ["Test restart escalation on a rest_for_one supervisor."]; -rest_for_one_escalation(suite) -> []; +%% Test restart escalation on a rest_for_one supervisor. rest_for_one_escalation(Config) when is_list(Config) -> process_flag(trap_exit, true), Child1 = {child1, {supervisor_1, start_child, []}, permanent, 1000, @@ -1023,11 +951,8 @@ rest_for_one_escalation(Config) when is_list(Config) -> check_exit([CPid2, SupPid]). %%------------------------------------------------------------------------- -child_unlink(doc)-> - ["Test that the supervisor does not hang forever if " - "the child unliks and then is terminated by the supervisor."]; -child_unlink(suite) -> - []; +%% Test that the supervisor does not hang forever if the child unliks +%% and then is terminated by the supervisor. child_unlink(Config) when is_list(Config) -> {ok, SupPid} = start_link({ok, {{one_for_one, 2, 3600}, []}}), @@ -1052,10 +977,7 @@ child_unlink(Config) when is_list(Config) -> test_server:fail(supervisor_hangs) end. %%------------------------------------------------------------------------- -tree(doc) -> - ["Test a basic supervison tree."]; -tree(suite) -> - []; +%% Test a basic supervison tree. tree(Config) when is_list(Config) -> process_flag(trap_exit, true), @@ -1131,11 +1053,9 @@ tree(Config) when is_list(Config) -> [] = supervisor:which_children(NewSup2), [0,0,0,0] = get_child_counts(NewSup2). + %%------------------------------------------------------------------------- -count_children_memory(doc) -> - ["Test that count_children does not eat memory."]; -count_children_memory(suite) -> - []; +%% Test that count_children does not eat memory. count_children_memory(Config) when is_list(Config) -> process_flag(trap_exit, true), Child = {child, {supervisor_1, start_child, []}, temporary, 1000, @@ -1177,12 +1097,12 @@ count_children_memory(Config) when is_list(Config) -> case (Size5 =< Size4) of true -> ok; false -> - test_server:fail({count_children, used_more_memory}) + test_server:fail({count_children, used_more_memory,Size4,Size5}) end, case Size7 =< Size6 of true -> ok; false -> - test_server:fail({count_children, used_more_memory}) + test_server:fail({count_children, used_more_memory,Size6,Size7}) end, [terminate(SupPid, Pid, child, kill) || {undefined, Pid, worker, _Modules} <- Children3], @@ -1193,12 +1113,9 @@ proc_memory() -> erlang:memory(processes_used). %%------------------------------------------------------------------------- -do_not_save_start_parameters_for_temporary_children(doc) -> - ["Temporary children shall not be restarted so they should not " - "save start parameters, as it potentially can " - "take up a huge amount of memory for no purpose."]; -do_not_save_start_parameters_for_temporary_children(suite) -> - []; +%% Temporary children shall not be restarted so they should not save +%% start parameters, as it potentially can take up a huge amount of +%% memory for no purpose. do_not_save_start_parameters_for_temporary_children(Config) when is_list(Config) -> process_flag(trap_exit, true), dont_save_start_parameters_for_temporary_children(one_for_all), @@ -1220,11 +1137,8 @@ child_spec({Name, MFA, RestartType, Shutdown, Type, Modules}, N) -> {NewName, MFA, RestartType, Shutdown, Type, Modules}. %%------------------------------------------------------------------------- -do_not_save_child_specs_for_temporary_children(doc) -> - ["Temporary children shall not be restarted so supervisors should " - "not save their spec when they terminate"]; -do_not_save_child_specs_for_temporary_children(suite) -> - []; +%% Temporary children shall not be restarted so supervisors should not +%% save their spec when they terminate. do_not_save_child_specs_for_temporary_children(Config) when is_list(Config) -> process_flag(trap_exit, true), dont_save_child_specs_for_temporary_children(one_for_all, kill), @@ -1373,13 +1287,18 @@ simple_one_for_one_scale_many_temporary_children(_Config) -> end || _<- lists:seq(1,10000)], {T2,done} = timer:tc(?MODULE,terminate_all_children,[C2]), - Scaling = T2 div T1, - if Scaling > 20 -> - %% The scaling shoul be linear (i.e.10, really), but we - %% give some extra here to avoid failing the test - %% unecessarily. - ?t:fail({bad_scaling,Scaling}); + if T1 > 0 -> + Scaling = T2 div T1, + if Scaling > 20 -> + %% The scaling shoul be linear (i.e.10, really), but we + %% give some extra here to avoid failing the test + %% unecessarily. + ?t:fail({bad_scaling,Scaling}); + true -> + ok + end; true -> + %% Means T2 div T1 -> infinity ok end. diff --git a/lib/stdlib/test/tar_SUITE.erl b/lib/stdlib/test/tar_SUITE.erl index 9ad3936928..5bc34e35af 100644 --- a/lib/stdlib/test/tar_SUITE.erl +++ b/lib/stdlib/test/tar_SUITE.erl @@ -533,7 +533,7 @@ symlinks(Config) when is_list(Config) -> ?line ok = file:make_dir(Dir), ?line ABadSymlink = filename:join(Dir, "bad_symlink"), ?line PointsTo = "/a/definitely/non_existing/path", - ?line Res = case file:make_symlink("/a/definitely/non_existing/path", ABadSymlink) of + ?line Res = case make_symlink("/a/definitely/non_existing/path", ABadSymlink) of {error, enotsup} -> {skip, "Symbolic links not supported on this platform"}; ok -> @@ -544,7 +544,30 @@ symlinks(Config) when is_list(Config) -> %% Clean up. ?line delete_files([Dir]), Res. - + +make_symlink(Path, Link) -> + case os:type() of + {win32,_} -> + %% Symlinks on Windows have two problems: + %% 1) file:read_link_info/1 cannot read out the target + %% of the symlink if the target does not exist. + %% That is possible (but not easy) to fix in the + %% efile driver. + %% + %% 2) Symlinks to files and directories are different + %% creatures. If the target is not existing, the + %% symlink will be created to be of the file-pointing + %% type. That can be partially worked around in erl_tar + %% by creating all symlinks when the end of the tar + %% file has been reached. + %% + %% But for now, pretend that there are no symlinks on + %% Windows. + {error, enotsup}; + _ -> + file:make_symlink(Path, Link) + end. + symlinks(Dir, BadSymlink, PointsTo) -> ?line Tar = filename:join(Dir, "symlink.tar"), ?line DerefTar = filename:join(Dir, "dereference.tar"), @@ -743,9 +766,9 @@ run_in_short_tempdir(Config, Fun) -> %% We need a base directory with a much shorter pathname than %% priv_dir. We KNOW that priv_dir is located four levels below %% the directory that common_test puts the ct_run.* directories - %% in. That fact is not documented, but an usually reliable source + %% in. That fact is not documented, but a usually reliable source %% assured me that the directory structure is unlikely to change - %% in future versions of common_test because of backward + %% in future versions of common_test because of backwards %% compatibility (tools developed by users of common_test depend %% on the current directory layout). Base = lists:foldl(fun(_, D) -> |