aboutsummaryrefslogtreecommitdiffstats
path: root/system
diff options
context:
space:
mode:
Diffstat (limited to 'system')
-rw-r--r--system/COPYRIGHT2
-rw-r--r--system/README78
-rw-r--r--system/doc/definitions/term.defs1
-rw-r--r--system/doc/design_principles/Makefile17
-rw-r--r--system/doc/design_principles/applications.xml162
-rw-r--r--system/doc/design_principles/appup_cookbook.xml5
-rw-r--r--system/doc/design_principles/book.xml2
-rw-r--r--system/doc/design_principles/code_lock.diabin0 -> 2945 bytes
-rw-r--r--system/doc/design_principles/code_lock.pngbin0 -> 59827 bytes
-rw-r--r--system/doc/design_principles/code_lock_2.diabin0 -> 2956 bytes
-rw-r--r--system/doc/design_principles/code_lock_2.pngbin0 -> 55553 bytes
-rw-r--r--system/doc/design_principles/des_princ.xml8
-rw-r--r--system/doc/design_principles/distributed_applications.xml2
-rw-r--r--system/doc/design_principles/events.xml2
-rw-r--r--system/doc/design_principles/fsm.xml12
-rw-r--r--system/doc/design_principles/gen_server_concepts.xml2
-rw-r--r--system/doc/design_principles/included_applications.xml2
-rw-r--r--system/doc/design_principles/part.xml3
-rw-r--r--system/doc/design_principles/release_handling.xml4
-rw-r--r--system/doc/design_principles/release_structure.xml2
-rw-r--r--system/doc/design_principles/spec_proc.xml33
-rw-r--r--system/doc/design_principles/statem.xml1738
-rw-r--r--system/doc/design_principles/sup_princ.xml15
-rw-r--r--system/doc/design_principles/xmlfiles.mk3
-rw-r--r--system/doc/efficiency_guide/Makefile2
-rw-r--r--system/doc/efficiency_guide/advanced.xml24
-rw-r--r--system/doc/efficiency_guide/appendix.xml2
-rw-r--r--system/doc/efficiency_guide/binaryhandling.xml8
-rw-r--r--system/doc/efficiency_guide/book.xml2
-rw-r--r--system/doc/efficiency_guide/commoncaveats.xml2
-rw-r--r--system/doc/efficiency_guide/drivers.xml2
-rw-r--r--system/doc/efficiency_guide/functions.xml2
-rw-r--r--system/doc/efficiency_guide/introduction.xml2
-rw-r--r--system/doc/efficiency_guide/listhandling.xml2
-rw-r--r--system/doc/efficiency_guide/myths.xml2
-rw-r--r--system/doc/efficiency_guide/part.xml2
-rw-r--r--system/doc/efficiency_guide/processes.xml2
-rw-r--r--system/doc/efficiency_guide/profiling.xml10
-rw-r--r--system/doc/efficiency_guide/tablesDatabases.xml2
-rw-r--r--system/doc/efficiency_guide/xmlfiles.mk2
-rw-r--r--system/doc/embedded/Makefile2
-rw-r--r--system/doc/embedded/book.xml2
-rw-r--r--system/doc/embedded/embedded_nt.xml6
-rw-r--r--system/doc/embedded/embedded_solaris.xml16
-rw-r--r--system/doc/embedded/intro.xml2
-rw-r--r--system/doc/embedded/part.xml2
-rw-r--r--system/doc/embedded/starting.xml10
-rw-r--r--system/doc/embedded/target.xml2
-rw-r--r--system/doc/embedded/vme_problems.xml2
-rw-r--r--system/doc/embedded/xmlfiles.mk2
-rw-r--r--system/doc/embedded/xntp.xml2
-rw-r--r--system/doc/getting_started/Makefile2
-rw-r--r--system/doc/getting_started/book.xml2
-rw-r--r--system/doc/getting_started/conc_prog.xml2
-rw-r--r--system/doc/getting_started/intro.xml2
-rw-r--r--system/doc/getting_started/part.xml2
-rw-r--r--system/doc/getting_started/records_macros.xml2
-rw-r--r--system/doc/getting_started/robustness.xml2
-rw-r--r--system/doc/getting_started/seq_prog.xml2
-rw-r--r--system/doc/getting_started/xmlfiles.mk2
-rw-r--r--system/doc/installation_guide/Makefile2
-rw-r--r--system/doc/installation_guide/book.xml2
-rw-r--r--system/doc/installation_guide/install-binary.xml2
-rw-r--r--system/doc/installation_guide/part.xml2
-rw-r--r--system/doc/installation_guide/xmlfiles.mk2
-rw-r--r--system/doc/oam/Makefile2
-rw-r--r--system/doc/oam/book.xml2
-rw-r--r--system/doc/oam/oam_intro.xml12
-rw-r--r--system/doc/oam/part.xml2
-rw-r--r--system/doc/oam/xmlfiles.mk2
-rw-r--r--system/doc/programming_examples/Makefile2
-rw-r--r--system/doc/programming_examples/book.xml2
-rw-r--r--system/doc/programming_examples/funs.xmlsrc4
-rw-r--r--system/doc/programming_examples/list_comprehensions.xml2
-rw-r--r--system/doc/programming_examples/part.xml2
-rw-r--r--system/doc/programming_examples/records.xml4
-rw-r--r--system/doc/programming_examples/xmlfiles.mk2
-rw-r--r--system/doc/reference_manual/Makefile2
-rw-r--r--system/doc/reference_manual/book.xml2
-rw-r--r--system/doc/reference_manual/code_loading.xml55
-rw-r--r--system/doc/reference_manual/expressions.xml53
-rw-r--r--system/doc/reference_manual/macros.xml52
-rw-r--r--system/doc/reference_manual/modules.xml3
-rw-r--r--system/doc/reference_manual/part.xml2
-rw-r--r--system/doc/reference_manual/patterns.xml2
-rw-r--r--system/doc/reference_manual/processes.xml4
-rw-r--r--system/doc/reference_manual/typespec.xml77
-rw-r--r--system/doc/reference_manual/xmlfiles.mk2
-rw-r--r--system/doc/system_architecture_intro/Makefile2
-rw-r--r--system/doc/system_architecture_intro/book.xml2
-rw-r--r--system/doc/system_architecture_intro/part.xml2
-rw-r--r--system/doc/system_architecture_intro/sys_arch_intro.xml2
-rw-r--r--system/doc/system_architecture_intro/xmlfiles.mk2
-rw-r--r--system/doc/system_principles/Makefile2
-rw-r--r--system/doc/system_principles/book.xml2
-rw-r--r--system/doc/system_principles/create_target.xmlsrc14
-rw-r--r--system/doc/system_principles/error_logging.xml2
-rw-r--r--system/doc/system_principles/part.xml2
-rw-r--r--system/doc/system_principles/upgrade.xml2
-rw-r--r--system/doc/system_principles/versions.xml6
-rw-r--r--system/doc/system_principles/xmlfiles.mk2
-rw-r--r--system/doc/top/Makefile10
-rw-r--r--system/doc/top/book.xml2
-rw-r--r--system/doc/top/src/erl_html_tools.erl30
-rw-r--r--system/doc/top/src/erlresolvelinks.erl2
-rw-r--r--system/doc/top/src/otp_man_index.erl2
-rw-r--r--system/doc/top/templates/applications.html.src2
-rw-r--r--system/doc/top/templates/index.html.src38
-rw-r--r--system/doc/tutorial/Makefile2
-rw-r--r--system/doc/tutorial/appendix.xmlsrc2
-rw-r--r--system/doc/tutorial/book.xml2
-rw-r--r--system/doc/tutorial/c_port.xmlsrc4
-rw-r--r--system/doc/tutorial/distribution.xml2
-rw-r--r--system/doc/tutorial/ei.c2
-rw-r--r--system/doc/tutorial/example.xmlsrc6
-rw-r--r--system/doc/tutorial/part.xml2
-rw-r--r--system/doc/tutorial/xmlfiles.mk2
117 files changed, 2295 insertions, 386 deletions
diff --git a/system/COPYRIGHT b/system/COPYRIGHT
index 0d0668974d..ef76b66f6b 100644
--- a/system/COPYRIGHT
+++ b/system/COPYRIGHT
@@ -5,7 +5,7 @@ This software is subject to the following Copyrights and Licenses:
%CopyrightBegin%
-Copyright Ericsson AB 1997-2012. All Rights Reserved.
+Copyright Ericsson AB 1997-2016. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/system/README b/system/README
deleted file mode 100644
index 97ec9177c4..0000000000
--- a/system/README
+++ /dev/null
@@ -1,78 +0,0 @@
-Erlang/OTP December 6, 2013
-
-
-Release of Erlang 5.10.4/OTP R16B03
-
-
-1. GENERAL
- -------
-
-1.1 Installation Guide
-
- The installation guide can be found in
-
- <inst-root>doc/installation_guide/users_guide.html
-
-1.2 Java
-
- The Java sources were compiled using Java version 1.5.
-
-1.3 Disk space
-
- An installation of Erlang/OTP needs approximately 300 MB of
- disk space.
-
-1.4 The package contains HTML documentation. You can also get this
- documentation preformatted for printing in PDF format from
-
- http://www.erlang.se/doc/
-
- This site also contains HTML documentation for older releases
- as a reference.
-
-1.5 The Erlang system can run old BEAM files compiled with R11B-2
- or later (and almost all BEAM files compiled with R11B-0 or
- R11B-1). BEAM files from R10B or earlier are not supported.
-
- To get the best performance, you should recompile your
- application code with the R15B compiler.
-
-
-2. NOTES ABOUT THE SOLARIS VERSION
- -------------------------------
-
-2.1 For the Sparc Solaris environment, Solaris10 (2.10) and above is
- supported. The emulator runs on older Solaris 8 (2.8) versions
- and above. Older Solaris versions are neither tested nor supported.
- Also an Ultrasparc (sun4u architecture) is required.
-
-
-3. NOTES ABOUT THE VXWORKS VERSION
- -------------------------------
-
-3.1 The platform VxWorks is discontinued in the sense that only the
- libraries (erl_interface and ic's libraries) are supported. The VxWorks
- release is still packaged as a full release, but no support will be
- available for anything but the communication libraries.
-
-4 NOTES ABOUT THE LINUX VERSIONS
- -----------------------------
-
-4.1 The following linux distributions/version combinations are supported
- and tested:
-
- SuSE 10.1 x86, SuSE 10.1 x86_64, SuSE 11.0 x86, SuSE 11.0 x86_64
-
-5. APPLICATIONS NOTES
- ------------------
-
-
-6. MORE INFORMATION
- ----------------
-
- Commercial customers please visit http://www.erlang.se to find
- releases and more information. Commercial support is given through
-
- Open source users please visit http://www.erlang.org and direct
- problems to the open source community through the mailing list.
diff --git a/system/doc/definitions/term.defs b/system/doc/definitions/term.defs
index 6091a46a20..921175a7f0 100644
--- a/system/doc/definitions/term.defs
+++ b/system/doc/definitions/term.defs
@@ -76,6 +76,7 @@ the module Erlang in the application kernel","kenneth"},
{"gen_event","gen_event","A behaviour used for programming event handling mechanisms, such as alarm handlers, error loggers, and plug-and-play handlers.","mbj"},
{"gen_fsm","gen_fsm","A behaviour used for programming finite state machines.","mbj"},
{"gen_server","gen_server","A behaviour used for programming client-server processes.","mbj"},
+{"gen_statem","gen_statem","A behaviour used for programming generic state machines.","raimo"},
{"gterm","Global Glossary Database","A glossary database used to list common acronymns and defintions etc.","jocke"},
{"xref","xref","A cross reference tool that can be used for finding dependencies between functions, modules, applications and releases. Part of the Tools application.","gunilla"},
{"GSlong","Graphics System","A library module which provides a graphics interface for Erlang.","mbj"},
diff --git a/system/doc/design_principles/Makefile b/system/doc/design_principles/Makefile
index 29df484279..937b3e28c8 100644
--- a/system/doc/design_principles/Makefile
+++ b/system/doc/design_principles/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2012. All Rights Reserved.
+# Copyright Ericsson AB 1997-2016. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -58,6 +58,12 @@ GIF_FILES = \
sup5.gif \
sup6.gif
+PNG_FILES = \
+ code_lock.png \
+ code_lock_2.png
+
+IMAGE_FILES = $(GIF_FILES) $(PNG_FILES)
+
XML_FILES = \
$(BOOK_FILES) $(XML_CHAPTER_FILES) \
$(XML_PART_FILES)
@@ -85,13 +91,16 @@ _create_dirs := $(shell mkdir -p $(HTMLDIR))
$(HTMLDIR)/%.gif: %.gif
$(INSTALL_DATA) $< $@
+$(HTMLDIR)/%.png: %.png
+ $(INSTALL_DATA) $< $@
+
docs: html
local_docs: PDFDIR=../../pdf
-html: $(HTML_UG_FILE) gifs
+html: $(HTML_UG_FILE) images
-gifs: $(GIF_FILES:%=$(HTMLDIR)/%)
+images: $(IMAGE_FILES:%=$(HTMLDIR)/%)
debug opt:
@@ -109,7 +118,7 @@ release_docs_spec: docs
# $(INSTALL_DIR) "$(RELEASE_PATH)/pdf"
# $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELEASE_PATH)/pdf"
$(INSTALL_DIR) $(RELSYSDIR)
- $(INSTALL_DATA) $(GIF_FILES) $(HTMLDIR)/*.html \
+ $(INSTALL_DATA) $(IMAGE_FILES) $(HTMLDIR)/*.html \
$(RELSYSDIR)
diff --git a/system/doc/design_principles/applications.xml b/system/doc/design_principles/applications.xml
index 4d73e0fc66..c673fde07e 100644
--- a/system/doc/design_principles/applications.xml
+++ b/system/doc/design_principles/applications.xml
@@ -4,14 +4,14 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2014</year>
+ <year>1997</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
@@ -19,7 +19,7 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-
+
</legalnotice>
<title>Applications</title>
@@ -172,31 +172,136 @@ ch_app:stop([])</code>
</section>
<section>
- <marker id="app_dir"></marker>
- <title>Directory Structure</title>
- <p>When packaging code using <c>systools</c>, the code for each
- application is placed in a separate directory,
- <c>lib/Application-Vsn</c>, where <c>Vsn</c> is the version number.</p>
- <p>This can be useful to know, even if <c>systools</c> is not used,
- since Erlang/OTP is packaged according to the OTP principles
- and thus comes with this directory structure. The code server
- (see the <c>code(3)</c> manual page in Kernel) automatically
- uses code from
- the directory with the highest version number, if more than one
- version of an application is present.</p>
- <p>The application directory structure can also be used in the
- development environment. The version number can then
- be omitted from the name.</p>
- <p>The application directory has the following sub-directories:</p>
- <list type="bulleted">
- <item><c>src</c> - Contains the Erlang source code.</item>
- <item><c>ebin</c> - Contains the Erlang object code, the
- <c>beam</c> files. The <c>.app</c> file is also placed here.</item>
- <item><c>priv</c> - Used for application specific files. For
- example, C executables are placed here. The function
- <c>code:priv_dir/1</c> is to be used to access this directory.</item>
- <item><c>include</c> - Used for include files.</item>
- </list>
+ <marker id="app_dir"></marker>
+ <title>Directory Structure</title>
+ <p>When packaging code using <c>systools</c>, the code for each
+ application is placed in a separate directory,
+ <c>lib/Application-Vsn</c>, where <c>Vsn</c> is the version number.</p>
+ <p>This can be useful to know, even if <c>systools</c> is not used,
+ since Erlang/OTP is packaged according to the OTP principles
+ and thus comes with a specific directory structure. The code server
+ (see the <seealso marker="kernel:code"><c>code(3)</c></seealso> manual
+ page in Kernel) automatically uses code from
+ the directory with the highest version number, if more than one
+ version of an application is present.</p>
+ <section>
+ <title>Directory Structure guidelines for a Development Environment</title>
+ <p>Any directory structure for development will suffice as long as the released directory structure
+ adhere to the <seealso marker="#app_dir_released">description below</seealso>,
+ but it is encouraged that the same directory structure
+ also be used in a development environment. The version number should be omitted from the
+ application directory name since this is an artifact of the release step.
+ </p>
+ <p> Some sub-directories are <em>required</em>. Some sub-directories are <em>optional</em>, meaning that it should
+ only be used if the application itself requires it. Finally, some sub-directories are <em>recommended</em>,
+ meaning it is encouraged that it is used and used as described here. For example, both documentation
+ and tests are encouraged to exist in an application for it to be deemed a proper OTP application.</p>
+<code type="none">
+ ─ ${application}
+   ├── doc
+ │   ├── internal
+ │   ├── examples
+ │   └── src
+   ├── include
+   ├── priv
+   ├── src
+ │   └── ${application}.app.src
+   └── test
+</code>
+ <list type="bulleted">
+ <item><c>src</c> - Required. Contains the Erlang source code, the source of the <c>.app</c> file
+ and internal include files used by the application itself. Additional sub-directories within
+ <c>src</c> can be used as namespaces to organize source files. These directories should never
+ be deeper than one level.</item>
+ <item><c>priv</c> - Optional. Used for application specific files. </item>
+ <item><c>include</c> - Optional. Used for public include files that must be reachable from
+ other applications.</item>
+ <item><c>doc</c> - Recommended. Any source documentation should be placed in sub-directories here.</item>
+ <item><c>doc/internal</c> - Recommended. Any documentation that describes implementation details about
+ this application, not intended for publication, should be placed here.</item>
+ <item><c>doc/examples</c> - Recommended. Source code for examples on how to use this application should
+ be placed here. It is encouraged that examples are sourced to the public documentation from
+ this directory.</item>
+ <item><c>doc/src</c> - Recommended. All source files for documentation, such as Markdown, AsciiDoc or
+ XML-files, should be placed here.</item>
+ <item><c>test</c> - Recommended. All files regarding tests, such as test suites and test specifications,
+ should be placed here. </item>
+ </list>
+
+ <p>Other directories in the development environment may be needed. If source code from languages other
+ than Erlang is used, for instance C-code for NIFs, that code should be placed in a separate directory.
+ By convention it is recommended to prefix such directories with the language name, for example
+ <c>c_src</c> for C, <c>java_src</c> for Java or <c>go_src</c> for Go. Directories with <c>_src</c>
+ suffix indicates that it is a part of the application and the compilation step. The final build artifacts
+ should target the <c>priv/lib</c> or <c>priv/bin</c> directories.</p>
+ <p>The <c>priv</c> directory holds assets that the application needs during runtime. Executables should
+ reside in <c>priv/bin</c> and dynamically-linked libraries should reside in <c>priv/lib</c>. Other assets
+ are free to reside within the <c>priv</c> directory but it is recommended it does so in a structured manner.</p>
+ <p>Source files from other languages that generate Erlang code, such as ASN.1 or Mibs, should be placed
+ in directories, at the top level or in <c>src</c>, with the same name as the source language, for example
+ <c>asn1</c> and <c>mibs</c>. Build artifacts should be placed in their respective language directory,
+ such as <c>src</c> for Erlang code or <c>java_src</c> for Java code.</p>
+ <p>The <c>.app</c> file for release may reside in the <c>ebin</c>-directory in a development environment
+ but it is encouraged that this is an artifact of the build step. By convention a <c>.app.src</c> file
+ is used, which resides in the <c>src</c> directory. This file is nearly identical as the
+ <c>.app</c> file but certain fields may be replaced during the build step, such as the application version.</p>
+ <p>Directory names should not be capitalized.</p>
+ <p>It is encouraged to omit empty directories.</p>
+
+ </section>
+
+ <section>
+ <marker id="app_dir_released"></marker>
+ <title>Directory Structure for a Released System</title>
+ <p>A released application must follow a certain structure.
+ </p>
+<code type="none">
+ ─ ${application}-${version}
+   ├── bin
+   ├── doc
+ │   ├── html
+ │   ├── man[1-9]
+ │   ├── pdf
+ │   ├── internal
+ │   └── examples
+   ├── ebin
+ │   └── ${application}.app
+   ├── include
+   ├── priv
+ │   ├── lib
+ │   └── bin
+   └── src
+</code>
+ <list type="bulleted">
+ <item><c>src</c> - Optional. Contains the Erlang source code and internal include files
+ used by the application itself. This directory is no longer required in a released application.</item>
+ <item><c>ebin</c> - Required. Contains the Erlang object code, the <c>beam</c> files.
+ The <c>.app</c> file must also be placed here.</item>
+ <item><c>priv</c> - Optional. Used for application specific files. <c>code:priv_dir/1</c>
+ is to be used to access this directory.</item>
+ <item><c>priv/lib</c> - Recommended. Any shared-object files that are used by the application,
+ such as NIFs or linked-in-drivers, should be placed here.</item>
+ <item><c>priv/bin</c> - Recommended. Any executable that is used by the application,
+ such as port-programs, should be placed here.</item>
+ <item><c>include</c> - Optional. Used for public include files that must be reachable from
+ other applications.</item>
+ <item><c>bin</c> - Optional. Any executable that is a product of the application,
+ such as escripts or shell-scripts, should be placed here.</item>
+ <item><c>doc</c> - Optional. Any released documentation should be placed in
+ sub-directories here.</item>
+ <item><c>doc/man1</c> - Recommended. Man pages for Application executables.</item>
+ <item><c>doc/man3</c> - Recommended. Man pages for module APIs.</item>
+ <item><c>doc/man6</c> - Recommended. Man pages for Application overview.</item>
+ <item><c>doc/html</c> - Optional. HTML pages for the entire Application.</item>
+ <item><c>doc/pdf</c> - Optional. PDF documentation for the entire Application.</item>
+ </list>
+
+ <p>The <c>src</c> directory could be useful to release for debugging purposes but is not required.
+ The <c>include</c> directory should only be released if the applications has public include files.</p>
+ <p>The only documentation that is recommended to be released in this way are the man pages. HTML and PDF
+ will normally be distributed in some other manner.</p>
+ <p>It is encouraged to omit empty directories.</p>
+ </section>
</section>
<section>
@@ -381,4 +486,3 @@ application:start(Application, Type)</code>
<c>shutdown</c>, not <c>normal</c>.</p>
</section>
</chapter>
-
diff --git a/system/doc/design_principles/appup_cookbook.xml b/system/doc/design_principles/appup_cookbook.xml
index 31335197d7..4f23c42c59 100644
--- a/system/doc/design_principles/appup_cookbook.xml
+++ b/system/doc/design_principles/appup_cookbook.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2014</year>
+ <year>2003</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -50,7 +50,8 @@
<p>In a system implemented according to the OTP design principles,
all processes, except system processes and special processes,
reside in one of the behaviours <c>supervisor</c>,
- <c>gen_server</c>, <c>gen_fsm</c>, or <c>gen_event</c>. These
+ <c>gen_server</c>, <c>gen_fsm</c>,
+ <c>gen_statem</c> or <c>gen_event</c>. These
belong to the STDLIB application and upgrading/downgrading
normally requires an emulator restart.</p>
<p>OTP thus provides no support for changing residence modules except
diff --git a/system/doc/design_principles/book.xml b/system/doc/design_principles/book.xml
index 663551df2f..a734f1d1e4 100644
--- a/system/doc/design_principles/book.xml
+++ b/system/doc/design_principles/book.xml
@@ -4,7 +4,7 @@
<book xmlns:xi="http://www.w3.org/2001/XInclude">
<header titlestyle="normal">
<copyright>
- <year>1997</year><year>2013</year>
+ <year>1997</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/design_principles/code_lock.dia b/system/doc/design_principles/code_lock.dia
new file mode 100644
index 0000000000..eaa2aca5b0
--- /dev/null
+++ b/system/doc/design_principles/code_lock.dia
Binary files differ
diff --git a/system/doc/design_principles/code_lock.png b/system/doc/design_principles/code_lock.png
new file mode 100644
index 0000000000..40bd35fc74
--- /dev/null
+++ b/system/doc/design_principles/code_lock.png
Binary files differ
diff --git a/system/doc/design_principles/code_lock_2.dia b/system/doc/design_principles/code_lock_2.dia
new file mode 100644
index 0000000000..3b9ba554d8
--- /dev/null
+++ b/system/doc/design_principles/code_lock_2.dia
Binary files differ
diff --git a/system/doc/design_principles/code_lock_2.png b/system/doc/design_principles/code_lock_2.png
new file mode 100644
index 0000000000..3aca9dd5aa
--- /dev/null
+++ b/system/doc/design_principles/code_lock_2.png
Binary files differ
diff --git a/system/doc/design_principles/des_princ.xml b/system/doc/design_principles/des_princ.xml
index ba67a49585..8ab8661c2d 100644
--- a/system/doc/design_principles/des_princ.xml
+++ b/system/doc/design_principles/des_princ.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2013</year>
+ <year>1997</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -183,7 +183,7 @@ handle_cast({free, Ch}, Chs) ->
<item>The server name, in this example the atom
<c>ch2</c>, is hidden from the users of the client functions. This
means that the name can be changed without affecting them.</item>
- <item>The protcol (messages sent to and received from the server)
+ <item>The protocol (messages sent to and received from the server)
is also hidden. This is good programming practice and allows
one to change the protocol without changing the code using
the interface functions.</item>
@@ -226,7 +226,9 @@ free(Ch, {Alloc, Free} = Channels) ->
<item><p><seealso marker="gen_server_concepts">gen_server</seealso></p>
<p>For implementing the server of a client-server relation</p></item>
<item><p><seealso marker="fsm">gen_fsm</seealso></p>
- <p>For implementing finite-state machines</p></item>
+ <p>For implementing finite-state machines (Old)</p></item>
+ <item><p><seealso marker="statem">gen_statem</seealso></p>
+ <p>For implementing state machines (New)</p></item>
<item><p><seealso marker="events">gen_event</seealso></p>
<p>For implementing event handling functionality</p></item>
<item><p><seealso marker="sup_princ">supervisor</seealso></p>
diff --git a/system/doc/design_principles/distributed_applications.xml b/system/doc/design_principles/distributed_applications.xml
index f1624a9ad7..a1a0149eb5 100644
--- a/system/doc/design_principles/distributed_applications.xml
+++ b/system/doc/design_principles/distributed_applications.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2013</year>
+ <year>2003</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/design_principles/events.xml b/system/doc/design_principles/events.xml
index 3c9d0996dc..e37b8b460d 100644
--- a/system/doc/design_principles/events.xml
+++ b/system/doc/design_principles/events.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2013</year>
+ <year>1997</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/design_principles/fsm.xml b/system/doc/design_principles/fsm.xml
index f58b50cbff..4f2b75e6e8 100644
--- a/system/doc/design_principles/fsm.xml
+++ b/system/doc/design_principles/fsm.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2013</year>
+ <year>1997</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -30,6 +30,16 @@
<file>fsm.xml</file>
</header>
<marker id="gen_fsm behaviour"></marker>
+ <note>
+ <p>
+ There is a new behaviour
+ <seealso marker="statem"><c>gen_statem</c></seealso>
+ that is intended to replace <c>gen_fsm</c> for new code.
+ It has the same features and add some really useful.
+ This module will not be removed for the foreseeable future
+ to keep old state machine implementations running.
+ </p>
+ </note>
<p>This section is to be read with the <c>gen_fsm(3)</c> manual page
in STDLIB, where all interface functions and callback
functions are described in detail.</p>
diff --git a/system/doc/design_principles/gen_server_concepts.xml b/system/doc/design_principles/gen_server_concepts.xml
index f8f98918fa..c1b98189d5 100644
--- a/system/doc/design_principles/gen_server_concepts.xml
+++ b/system/doc/design_principles/gen_server_concepts.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2013</year>
+ <year>1997</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/design_principles/included_applications.xml b/system/doc/design_principles/included_applications.xml
index 3257795e5f..34501c0296 100644
--- a/system/doc/design_principles/included_applications.xml
+++ b/system/doc/design_principles/included_applications.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2013</year>
+ <year>2003</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/design_principles/part.xml b/system/doc/design_principles/part.xml
index 42fd3beb6a..6495211e04 100644
--- a/system/doc/design_principles/part.xml
+++ b/system/doc/design_principles/part.xml
@@ -4,7 +4,7 @@
<part xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>1997</year><year>2013</year>
+ <year>1997</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -31,6 +31,7 @@
<xi:include href="des_princ.xml"/>
<xi:include href="gen_server_concepts.xml"/>
<xi:include href="fsm.xml"/>
+ <xi:include href="statem.xml"/>
<xi:include href="events.xml"/>
<xi:include href="sup_princ.xml"/>
<xi:include href="spec_proc.xml"/>
diff --git a/system/doc/design_principles/release_handling.xml b/system/doc/design_principles/release_handling.xml
index 20ddc3dbf5..4f71ad4437 100644
--- a/system/doc/design_principles/release_handling.xml
+++ b/system/doc/design_principles/release_handling.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2014</year>
+ <year>2003</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -249,7 +249,7 @@
<p>If <c>Modules=dynamic</c>, which is the case for event
managers, the event manager process informs the release handler
about the list of currently installed event handlers
- (<c>gen_fsm</c>), and it is checked if the module name is in
+ (<c>gen_event</c>), and it is checked if the module name is in
this list instead.</p>
<p>The release handler suspends, asks for code change, and
resumes processes by calling the functions
diff --git a/system/doc/design_principles/release_structure.xml b/system/doc/design_principles/release_structure.xml
index 6e7ab06094..a0ab21c43f 100644
--- a/system/doc/design_principles/release_structure.xml
+++ b/system/doc/design_principles/release_structure.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2013</year>
+ <year>2003</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/design_principles/spec_proc.xml b/system/doc/design_principles/spec_proc.xml
index 3d7a88da3f..5b156ac263 100644
--- a/system/doc/design_principles/spec_proc.xml
+++ b/system/doc/design_principles/spec_proc.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2014</year>
+ <year>1997</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -522,9 +522,36 @@ init(Parent, Name, Module) ->
-module(db).
-behaviour(simple_server).
--export([init/0, handle_req/2, terminate/0]).
+-export([init/1, handle_req/2, terminate/0]).
...</code>
+
+ <p>The contracts specified with <c>-callback</c> attributes in
+ behaviour modules can be further refined by adding <c>-spec</c>
+ attributes in callback modules. This can be useful as
+ <c>-callback</c> contracts are usually generic. The same callback
+ module with contracts for the callbacks:</p>
+
+ <code type="none">
+-module(db).
+-behaviour(simple_server).
+
+-export([init/1, handle_req/2, terminate/0]).
+
+-record(state, {field1 :: [atom()], field2 :: integer()}).
+
+-type state() :: #state{}.
+-type request() :: {'store', term(), term()};
+ {'lookup', term()}.
+
+...
+
+-spec handle_req(request(), state()) -> {'ok', term()}.
+
+...</code>
+
+ <p>Each <c>-spec</c> contract is to be a subtype of the respective
+ <c>-callback</c> contract.</p>
+
</section>
</chapter>
-
diff --git a/system/doc/design_principles/statem.xml b/system/doc/design_principles/statem.xml
new file mode 100644
index 0000000000..f627145f9f
--- /dev/null
+++ b/system/doc/design_principles/statem.xml
@@ -0,0 +1,1738 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2016</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ </legalnotice>
+
+ <title>gen_statem Behavior</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ <file>statem.xml</file>
+ </header>
+ <marker id="gen_statem Behaviour" />
+ <p>
+ This section is to be read with the
+ <seealso marker="stdlib:gen_statem"><c>gen_statem(3)</c></seealso>
+ manual page in STDLIB, where all interface functions and callback
+ functions are described in detail.
+ </p>
+ <note>
+ <p>
+ This is a new behavior in Erlang/OTP 19.0.
+ It has been thoroughly reviewed, is stable enough
+ to be used by at least two heavy OTP applications, and is here to stay.
+ Depending on user feedback, we do not expect
+ but can find it necessary to make minor
+ not backward compatible changes into Erlang/OTP 20.0.
+ </p>
+ </note>
+
+<!-- =================================================================== -->
+
+ <section>
+ <marker id="Event-Driven State Machines" />
+ <title>Event-Driven State Machines</title>
+ <p>
+ Established Automata Theory does not deal much with
+ how a state transition is triggered,
+ but assumes that the output is a function
+ of the input (and the state) and that they are
+ some kind of values.
+ </p>
+ <p>
+ For an Event-Driven State Machine, the input is an event
+ that triggers a state transition and the output
+ is actions executed during the state transition.
+ It can analogously to the mathematical model of a
+ Finite-State Machine be described as
+ a set of relations of the following form:
+ </p>
+ <pre>
+State(S) x Event(E) -> Actions(A), State(S')</pre>
+ <p>These relations are interpreted as follows:
+ if we are in state <c>S</c> and event <c>E</c> occurs, we
+ are to perform actions <c>A</c> and make a transition to
+ state <c>S'</c>. Notice that <c>S'</c> can be equal to <c>S</c>.
+ </p>
+ <p>
+ As <c>A</c> and <c>S'</c> depend only on
+ <c>S</c> and <c>E</c>, the kind of state machine described
+ here is a Mealy Machine
+ (see, for example, the corresponding Wikipedia article).
+ </p>
+ <p>
+ Like most <c>gen_</c> behaviors, <c>gen_statem</c> keeps
+ a server <c>Data</c> besides the state. Because of this, and as
+ there is no restriction on the number of states
+ (assuming that there is enough virtual machine memory)
+ or on the number of distinct input events,
+ a state machine implemented with this behavior
+ is in fact Turing complete.
+ But it feels mostly like an Event-Driven Mealy Machine.
+ </p>
+ </section>
+
+<!-- =================================================================== -->
+
+ <section>
+ <marker id="Callback Modes" />
+ <title>Callback Modes</title>
+ <p>
+ The <c>gen_statem</c> behavior supports two callback modes:
+ </p>
+ <list type="bulleted">
+ <item>
+ <p>
+ In mode
+ <seealso marker="stdlib:gen_statem#type-callback_mode"><c>state_functions</c></seealso>,
+ the state transition rules are written as some Erlang
+ functions, which conform to the following convention:
+ </p>
+ <pre>
+StateName(EventType, EventContent, Data) ->
+ ... code for actions here ...
+ {next_state, NewStateName, NewData}.
+ </pre>
+ <p>
+ This form is used in most examples here for example in section
+ <seealso marker="#Example">Example</seealso>.
+ </p>
+ </item>
+ <item>
+ <p>
+ In mode
+ <seealso marker="stdlib:gen_statem#type-callback_mode"><c>handle_event_function</c></seealso>,
+ only one Erlang function provides all state transition rules:
+ </p>
+ <pre>
+handle_event(EventType, EventContent, State, Data) ->
+ ... code for actions here ...
+ {next_state, NewState, NewData}
+ </pre>
+ <p>
+ Se section
+ <seealso marker="#One Event Handler">One Event Handler</seealso>
+ for an example.
+ </p>
+ </item>
+ </list>
+ <p>
+ Both these modes allow other return tuples; see
+ <seealso marker="stdlib:gen_statem#Module:StateName/3"><c>Module:StateName/3</c></seealso>
+ in the <c>gen_statem</c> manual page.
+ These other return tuples can, for example, stop the machine,
+ execute state transition actions on the machine engine itself,
+ and send replies.
+ </p>
+
+ <section>
+ <marker id="Choosing the Callback Mode" />
+ <title>Choosing the Callback Mode</title>
+ <p>
+ The two
+ <seealso marker="#Callback Modes">callback modes</seealso>
+ give different possibilities
+ and restrictions, but one goal remains:
+ you want to handle all possible combinations of
+ events and states.
+ </p>
+ <p>
+ This can be done, for example, by focusing on one state at the time
+ and for every state ensure that all events are handled.
+ Alternatively, you can focus on one event at the time
+ and ensure that it is handled in every state.
+ You can also use a mix of these strategies.
+ </p>
+ <p>
+ With <c>state_functions</c>, you are restricted to use
+ atom-only states, and the <c>gen_statem</c> engine
+ branches depending on state name for you.
+ This encourages the callback module to gather
+ the implementation of all event actions particular
+ to one state in the same place in the code,
+ hence to focus on one state at the time.
+ </p>
+ <p>
+ This mode fits well when you have a regular state diagram,
+ like the ones in this chapter, which describes all events and actions
+ belonging to a state visually around that state,
+ and each state has its unique name.
+ </p>
+ <p>
+ With <c>handle_event_function</c>, you are free to mix strategies,
+ as all events and states are handled in the same callback function.
+ </p>
+ <p>
+ This mode works equally well when you want to focus on
+ one event at the time or on
+ one state at the time, but function
+ <seealso marker="stdlib:gen_statem#Module:handle_event/4"><c>Module:handle_event/4</c></seealso>
+ quickly grows too large to handle without branching to
+ helper functions.
+ </p>
+ <p>
+ The mode enables the use of non-atom states, for example,
+ complex states or even hierarchical states.
+ If, for example, a state diagram is largely alike
+ for the client side and the server side of a protocol,
+ you can have a state <c>{StateName,server}</c> or
+ <c>{StateName,client}</c>,
+ and make <c>StateName</c> determine where in the code
+ to handle most events in the state.
+ The second element of the tuple is then used to select
+ whether to handle special client-side or server-side events.
+ </p>
+ </section>
+ </section>
+
+<!-- =================================================================== -->
+
+ <section>
+ <marker id="State Enter Calls" />
+ <title>State Enter Calls</title>
+ <p>
+ The <c>gen_statem</c> behavior can regardless of callback mode
+ automatically
+ <seealso marker="stdlib:gen_statem#type-state_enter">
+ call the state callback
+ </seealso>
+ with special arguments whenever the state changes
+ so you can write state entry actions
+ near the rest of the state transition rules.
+ It typically looks like this:
+ </p>
+ <pre>
+StateName(enter, _OldState, Data) ->
+ ... code for state entry actions here ...
+ {keep_state, NewData};
+StateName(EventType, EventContent, Data) ->
+ ... code for actions here ...
+ {next_state, NewStateName, NewData}.</pre>
+ <p>
+ Depending on how your state machine is specified,
+ this can be a very useful feature,
+ but it forces you to handle the state enter calls in all states.
+ See also the
+ <seealso marker="#State Entry Actions">
+ State Entry Actions
+ </seealso>
+ chapter.
+ </p>
+ </section>
+
+<!-- =================================================================== -->
+
+ <section>
+ <marker id="Actions" />
+ <title>Actions</title>
+ <p>
+ In the first section
+ <seealso marker="#Event-Driven State Machines">
+ Event-Driven State Machines
+ </seealso>
+ actions were mentioned as a part of
+ the general state machine model. These general actions
+ are implemented with the code that callback module
+ <c>gen_statem</c> executes in an event-handling
+ callback function before returning
+ to the <c>gen_statem</c> engine.
+ </p>
+ <p>
+ There are more specific state-transition actions
+ that a callback function can order the <c>gen_statem</c>
+ engine to do after the callback function return.
+ These are ordered by returning a list of
+ <seealso marker="stdlib:gen_statem#type-action">actions</seealso>
+ in the
+ <seealso marker="stdlib:gen_statem#type-state_callback_result">return tuple</seealso>
+ from the
+ <seealso marker="stdlib:gen_statem#Module:StateName/3">callback function</seealso>.
+ These state transition actions affect the <c>gen_statem</c>
+ engine itself and can do the following:
+ </p>
+ <list type="bulleted">
+ <item>
+ <seealso marker="stdlib:gen_statem#type-postpone">
+ Postpone
+ </seealso>
+ the current event, see section
+ <seealso marker="#Postponing Events">Postponing Events</seealso>
+ </item>
+ <item>
+ <seealso marker="stdlib:gen_statem#type-hibernate">
+ Hibernate
+ </seealso>
+ the <c>gen_statem</c>, treated in
+ <seealso marker="#Hibernation">Hibernation</seealso>
+ </item>
+ <item>
+ Start a
+ <seealso marker="stdlib:gen_statem#type-state_timeout">
+ state time-out</seealso>,
+ read more in section
+ <seealso marker="#State Time-Outs">State Time-Outs</seealso>
+ </item>
+ <item>
+ Start an
+ <seealso marker="stdlib:gen_statem#type-event_timeout">event time-out</seealso>,
+ see more in section
+ <seealso marker="#Event Time-Outs">Event Time-Outs</seealso>
+ </item>
+ <item>
+ <seealso marker="stdlib:gen_statem#type-reply_action">
+ Reply
+ </seealso>
+ to a caller, mentioned at the end of section
+ <seealso marker="#All State Events">All State Events</seealso>
+ </item>
+ <item>
+ Generate the
+ <seealso marker="stdlib:gen_statem#type-action">
+ next event
+ </seealso>
+ to handle, see section
+ <seealso marker="#Self-Generated Events">Self-Generated Events</seealso>
+ </item>
+ </list>
+ <p>
+ For details, see the
+ <seealso marker="stdlib:gen_statem#type-action">
+ <c>gen_statem(3)</c>
+ </seealso>
+ manual page.
+ You can, for example, reply to many callers
+ and generate multiple next events to handle.
+ </p>
+ </section>
+
+<!-- =================================================================== -->
+
+ <section>
+ <marker id="Event Types" />
+ <title>Event Types</title>
+ <p>
+ Events are categorized in different
+ <seealso marker="stdlib:gen_statem#type-event_type">event types</seealso>.
+ Events of all types are handled in the same callback function,
+ for a given state, and the function gets
+ <c>EventType</c> and <c>EventContent</c> as arguments.
+ </p>
+ <p>
+ The following is a complete list of event types and where
+ they come from:
+ </p>
+ <taglist>
+ <tag><c>cast</c></tag>
+ <item>
+ Generated by
+ <seealso marker="stdlib:gen_statem#cast/2"><c>gen_statem:cast</c></seealso>.
+ </item>
+ <tag><c>{call,From}</c></tag>
+ <item>
+ Generated by
+ <seealso marker="stdlib:gen_statem#call/2"><c>gen_statem:call</c></seealso>,
+ where <c>From</c> is the reply address to use
+ when replying either through the state transition action
+ <c>{reply,From,Msg}</c> or by calling
+ <seealso marker="stdlib:gen_statem#reply/1"><c>gen_statem:reply</c></seealso>.
+ </item>
+ <tag><c>info</c></tag>
+ <item>
+ Generated by any regular process message sent to
+ the <c>gen_statem</c> process.
+ </item>
+ <tag><c>state_timeout</c></tag>
+ <item>
+ Generated by state transition action
+ <seealso marker="stdlib:gen_statem#type-state_timeout">
+ <c>{state_timeout,Time,EventContent}</c>
+ </seealso>
+ state timer timing out.
+ </item>
+ <tag><c>timeout</c></tag>
+ <item>
+ Generated by state transition action
+ <seealso marker="stdlib:gen_statem#type-event_timeout">
+ <c>{timeout,Time,EventContent}</c>
+ </seealso>
+ (or its short form <c>Time</c>)
+ event timer timing out.
+ </item>
+ <tag><c>internal</c></tag>
+ <item>
+ Generated by state transition
+ <seealso marker="stdlib:gen_statem#type-action">action</seealso>
+ <c>{next_event,internal,EventContent}</c>.
+ All event types above can also be generated using
+ <c>{next_event,EventType,EventContent}</c>.
+ </item>
+ </taglist>
+ </section>
+
+<!-- =================================================================== -->
+
+ <section>
+ <marker id="Example" />
+ <title>Example</title>
+ <p>
+ This example starts off as equivalent to the example in section
+ <seealso marker="fsm"><c>gen_fsm</c>&nbsp;Behavior</seealso>.
+ In later sections, additions and tweaks are made
+ using features in <c>gen_statem</c> that <c>gen_fsm</c> does not have.
+ The end of this chapter provides the example again
+ with all the added features.
+ </p>
+ <p>
+ A door with a code lock can be seen as a state machine.
+ Initially, the door is locked. When someone presses a button,
+ an event is generated.
+ Depending on what buttons have been pressed before,
+ the sequence so far can be correct, incomplete, or wrong.
+ If correct, the door is unlocked for 10 seconds (10,000 milliseconds).
+ If incomplete, we wait for another button to be pressed. If
+ wrong, we start all over, waiting for a new button sequence.
+ </p>
+ <image file="../design_principles/code_lock.png">
+ <icaption>Code Lock State Diagram</icaption>
+ </image>
+ <p>
+ This code lock state machine can be implemented using
+ <c>gen_statem</c> with the following callback module:
+ </p>
+ <code type="erl"><![CDATA[
+-module(code_lock).
+-behaviour(gen_statem).
+-define(NAME, code_lock).
+
+-export([start_link/1]).
+-export([button/1]).
+-export([init/1,callback_mode/0,terminate/3,code_change/4]).
+-export([locked/3,open/3]).
+
+start_link(Code) ->
+ gen_statem:start_link({local,?NAME}, ?MODULE, Code, []).
+
+button(Digit) ->
+ gen_statem:cast(?NAME, {button,Digit}).
+
+init(Code) ->
+ do_lock(),
+ Data = #{code => Code, remaining => Code},
+ {ok, locked, Data}.
+
+callback_mode() ->
+ state_functions.
+
+locked(
+ cast, {button,Digit},
+ #{code := Code, remaining := Remaining} = Data) ->
+ case Remaining of
+ [Digit] ->
+ do_unlock(),
+ {next_state, open, Data#{remaining := Code},
+ [{state_timeout,10000,lock}];
+ [Digit|Rest] -> % Incomplete
+ {next_state, locked, Data#{remaining := Rest}};
+ _Wrong ->
+ {next_state, locked, Data#{remaining := Code}}
+ end.
+
+open(state_timeout, lock, Data) ->
+ do_lock(),
+ {next_state, locked, Data};
+open(cast, {button,_}, Data) ->
+ {next_state, open, Data}.
+
+do_lock() ->
+ io:format("Lock~n", []).
+do_unlock() ->
+ io:format("Unlock~n", []).
+
+terminate(_Reason, State, _Data) ->
+ State =/= locked andalso do_lock(),
+ ok.
+code_change(_Vsn, State, Data, _Extra) ->
+ {ok, State, Data}.
+ ]]></code>
+ <p>The code is explained in the next sections.</p>
+ </section>
+
+<!-- =================================================================== -->
+
+ <section>
+ <marker id="Starting gen_statem" />
+ <title>Starting gen_statem</title>
+ <p>
+ In the example in the previous section, <c>gen_statem</c> is
+ started by calling <c>code_lock:start_link(Code)</c>:
+ </p>
+ <code type="erl"><![CDATA[
+start_link(Code) ->
+ gen_statem:start_link({local,?NAME}, ?MODULE, Code, []).
+ ]]></code>
+ <p>
+ <c>start_link</c> calls function
+ <seealso marker="stdlib:gen_statem#start_link/4"><c>gen_statem:start_link/4</c></seealso>,
+ which spawns and links to a new process, a <c>gen_statem</c>.
+ </p>
+ <list type="bulleted">
+ <item>
+ <p>
+ The first argument, <c>{local,?NAME}</c>, specifies
+ the name. In this case, the <c>gen_statem</c> is locally
+ registered as <c>code_lock</c> through the macro <c>?NAME</c>.
+ </p>
+ <p>
+ If the name is omitted, the <c>gen_statem</c> is not registered.
+ Instead its pid must be used. The name can also be specified
+ as <c>{global,Name}</c>, then the <c>gen_statem</c> is
+ registered using
+ <seealso marker="kernel:global#register_name/2"><c>global:register_name/2</c></seealso>
+ in Kernel.
+ </p>
+ </item>
+ <item>
+ <p>
+ The second argument, <c>?MODULE</c>, is the name of
+ the callback module, that is, the module where the callback
+ functions are located, which is this module.
+ </p>
+ <p>
+ The interface functions (<c>start_link/1</c> and <c>button/1</c>)
+ are located in the same module as the callback functions
+ (<c>init/1</c>, <c>locked/3</c>, and <c>open/3</c>).
+ It is normally good programming practice to have the client-side
+ code and the server-side code contained in one module.
+ </p>
+ </item>
+ <item>
+ <p>
+ The third argument, <c>Code</c>, is a list of digits, which
+ is the correct unlock code that is passed
+ to callback function <c>init/1</c>.
+ </p>
+ </item>
+ <item>
+ <p>
+ The fourth argument, <c>[]</c>, is a list of options.
+ For the available options, see
+ <seealso marker="stdlib:gen_statem#start_link/3"><c>gen_statem:start_link/3</c></seealso>.
+ </p>
+ </item>
+ </list>
+ <p>
+ If name registration succeeds, the new <c>gen_statem</c> process
+ calls callback function <c>code_lock:init(Code)</c>.
+ This function is expected to return <c>{ok, State, Data}</c>,
+ where <c>State</c> is the initial state of the <c>gen_statem</c>,
+ in this case <c>locked</c>; assuming that the door is locked to begin
+ with. <c>Data</c> is the internal server data of the <c>gen_statem</c>.
+ Here the server data is a <seealso marker="stdlib:maps">map</seealso>
+ with key <c>code</c> that stores
+ the correct button sequence, and key <c>remaining</c>
+ that stores the remaining correct button sequence
+ (the same as the <c>code</c> to begin with).
+ </p>
+
+ <code type="erl"><![CDATA[
+init(Code) ->
+ do_lock(),
+ Data = #{code => Code, remaining => Code},
+ {ok,locked,Data}.
+ ]]></code>
+ <p>Function
+ <seealso marker="stdlib:gen_statem#start_link/3"><c>gen_statem:start_link</c></seealso>
+ is synchronous. It does not return until the <c>gen_statem</c>
+ is initialized and is ready to receive events.
+ </p>
+ <p>
+ Function
+ <seealso marker="stdlib:gen_statem#start_link/3"><c>gen_statem:start_link</c></seealso>
+ must be used if the <c>gen_statem</c>
+ is part of a supervision tree, that is, started by a supervisor.
+ Another function,
+ <seealso marker="stdlib:gen_statem#start/3"><c>gen_statem:start</c></seealso>
+ can be used to start a standalone <c>gen_statem</c>, that is,
+ a <c>gen_statem</c> that is not part of a supervision tree.
+ </p>
+
+ <code type="erl"><![CDATA[
+callback_mode() ->
+ state_functions.
+ ]]></code>
+ <p>
+ Function
+ <seealso marker="stdlib:gen_statem#Module:callback_mode/0"><c>Module:callback_mode/0</c></seealso>
+ selects the
+ <seealso marker="#Callback Modes"><c>CallbackMode</c></seealso>
+ for the callback module, in this case
+ <seealso marker="stdlib:gen_statem#type-callback_mode"><c>state_functions</c></seealso>.
+ That is, each state has got its own handler function.
+ </p>
+
+ </section>
+
+<!-- =================================================================== -->
+
+ <section>
+ <marker id="Handling Events" />
+ <title>Handling Events</title>
+ <p>The function notifying the code lock about a button event is
+ implemented using
+ <seealso marker="stdlib:gen_statem#cast/2"><c>gen_statem:cast/2</c></seealso>:
+ </p>
+ <code type="erl"><![CDATA[
+button(Digit) ->
+ gen_statem:cast(?NAME, {button,Digit}).
+ ]]></code>
+ <p>
+ The first argument is the name of the <c>gen_statem</c> and must
+ agree with the name used to start it. So, we use the
+ same macro <c>?NAME</c> as when starting.
+ <c>{button,Digit}</c> is the event content.
+ </p>
+ <p>
+ The event is made into a message and sent to the <c>gen_statem</c>.
+ When the event is received, the <c>gen_statem</c> calls
+ <c>StateName(cast, Event, Data)</c>, which is expected to
+ return a tuple <c>{next_state, NewStateName, NewData}</c>,
+ or <c>{next_state, NewStateName, NewData, Actions}</c>.
+ <c>StateName</c> is the name of the current state and
+ <c>NewStateName</c> is the name of the next state to go to.
+ <c>NewData</c> is a new value for the server data of
+ the <c>gen_statem</c>, and <c>Actions</c> is a list of
+ actions on the <c>gen_statem</c> engine.
+ </p>
+ <code type="erl"><![CDATA[
+locked(
+ cast, {button,Digit},
+ #{code := Code, remaining := Remaining} = Data) ->
+ case Remaining of
+ [Digit] -> % Complete
+ do_unlock(),
+ {next_state, open, Data#{remaining := Code},
+ [{state_timeout,10000,lock}]};
+ [Digit|Rest] -> % Incomplete
+ {next_state, locked, Data#{remaining := Rest}};
+ [_|_] -> % Wrong
+ {next_state, locked, Data#{remaining := Code}}
+ end.
+
+open(state_timeout, lock, Data) ->
+ do_lock(),
+ {next_state, locked, Data};
+open(cast, {button,_}, Data) ->
+ {next_state, open, Data}.
+ ]]></code>
+ <p>
+ If the door is locked and a button is pressed, the pressed
+ button is compared with the next correct button.
+ Depending on the result, the door is either unlocked
+ and the <c>gen_statem</c> goes to state <c>open</c>,
+ or the door remains in state <c>locked</c>.
+ </p>
+ <p>
+ If the pressed button is incorrect, the server data
+ restarts from the start of the code sequence.
+ </p>
+ <p>
+ If the whole code is correct, the server changes states
+ to <c>open</c>.
+ </p>
+ <p>
+ In state <c>open</c>, a button event is ignored
+ by staying in the same state. This can also be done
+ by returning <c>{keep_state, Data}</c> or in this case
+ since <c>Data</c> unchanged even by returning
+ <c>keep_state_and_data</c>.
+ </p>
+ </section>
+
+ <section>
+ <marker id="State Time-Outs" />
+ <title>State Time-Outs</title>
+ <p>
+ When a correct code has been given, the door is unlocked and
+ the following tuple is returned from <c>locked/2</c>:
+ </p>
+ <code type="erl"><![CDATA[
+{next_state, open, Data#{remaining := Code},
+ [{state_timeout,10000,lock}]};
+ ]]></code>
+ <p>
+ 10,000 is a time-out value in milliseconds.
+ After this time (10 seconds), a time-out occurs.
+ Then, <c>StateName(state_timeout, lock, Data)</c> is called.
+ The time-out occurs when the door has been in state <c>open</c>
+ for 10 seconds. After that the door is locked again:
+ </p>
+ <code type="erl"><![CDATA[
+open(state_timeout, lock, Data) ->
+ do_lock(),
+ {next_state, locked, Data};
+ ]]></code>
+ <p>
+ The timer for a state time-out is automatically cancelled
+ when the state machine changes states. You can restart
+ a state time-out by setting it to a new time, which cancels
+ the running timer and starts a new. This implies that
+ you can cancel a state time-out by restarting it with
+ time <c>infinity</c>.
+ </p>
+ </section>
+
+<!-- =================================================================== -->
+
+ <section>
+ <marker id="All State Events" />
+ <title>All State Events</title>
+ <p>
+ Sometimes events can arrive in any state of the <c>gen_statem</c>.
+ It is convenient to handle these in a common state handler function
+ that all state functions call for events not specific to the state.
+ </p>
+ <p>
+ Consider a <c>code_length/0</c> function that returns
+ the length of the correct code
+ (that should not be sensitive to reveal).
+ We dispatch all events that are not state-specific
+ to the common function <c>handle_event/3</c>:
+ </p>
+ <code type="erl"><![CDATA[
+...
+-export([button/1,code_length/0]).
+...
+
+code_length() ->
+ gen_statem:call(?NAME, code_length).
+
+...
+locked(...) -> ... ;
+locked(EventType, EventContent, Data) ->
+ handle_event(EventType, EventContent, Data).
+
+...
+open(...) -> ... ;
+open(EventType, EventContent, Data) ->
+ handle_event(EventType, EventContent, Data).
+
+handle_event({call,From}, code_length, #{code := Code} = Data) ->
+ {keep_state, Data, [{reply,From,length(Code)}]}.
+ ]]></code>
+ <p>
+ This example uses
+ <seealso marker="stdlib:gen_statem#call/2"><c>gen_statem:call/2</c></seealso>,
+ which waits for a reply from the server.
+ The reply is sent with a <c>{reply,From,Reply}</c> tuple
+ in an action list in the <c>{keep_state, ...}</c> tuple
+ that retains the current state. This return form is convenient
+ when you want to stay in the current state but do not know or
+ care about what it is.
+ </p>
+ </section>
+
+<!-- =================================================================== -->
+
+ <section>
+ <marker id="One Event Handler" />
+ <title>One Event Handler</title>
+ <p>
+ If mode <c>handle_event_function</c> is used,
+ all events are handled in
+ <seealso marker="stdlib:gen_statem#Module:handle_event/4"><c>Module:handle_event/4</c></seealso>
+ and we can (but do not have to) use an event-centered approach
+ where we first branch depending on event
+ and then depending on state:
+ </p>
+ <code type="erl"><![CDATA[
+...
+-export([handle_event/4]).
+
+...
+callback_mode() ->
+ handle_event_function.
+
+handle_event(cast, {button,Digit}, State, #{code := Code} = Data) ->
+ case State of
+ locked ->
+ case maps:get(remaining, Data) of
+ [Digit] -> % Complete
+ do_unlock(),
+ {next_state, open, Data#{remaining := Code},
+ [{state_timeout,10000,lock}};
+ [Digit|Rest] -> % Incomplete
+ {keep_state, Data#{remaining := Rest}};
+ [_|_] -> % Wrong
+ {keep_state, Data#{remaining := Code}}
+ end;
+ open ->
+ keep_state_and_data
+ end;
+handle_event(state_timeout, lock, open, Data) ->
+ do_lock(),
+ {next_state, locked, Data}.
+
+...
+ ]]></code>
+ </section>
+
+<!-- =================================================================== -->
+
+ <section>
+ <marker id="Stopping" />
+ <title>Stopping</title>
+
+ <section>
+ <marker id="In a Supervision Tree" />
+ <title>In a Supervision Tree</title>
+ <p>
+ If the <c>gen_statem</c> is part of a supervision tree,
+ no stop function is needed.
+ The <c>gen_statem</c> is automatically terminated by its supervisor.
+ Exactly how this is done is defined by a
+ <seealso marker="sup_princ#shutdown">shutdown strategy</seealso>
+ set in the supervisor.
+ </p>
+ <p>
+ If it is necessary to clean up before termination, the shutdown
+ strategy must be a time-out value and the <c>gen_statem</c> must
+ in function <c>init/1</c> set itself to trap exit signals
+ by calling
+ <seealso marker="erts:erlang#process_flag/2"><c>process_flag(trap_exit, true)</c></seealso>:
+ </p>
+ <code type="erl"><![CDATA[
+init(Args) ->
+ process_flag(trap_exit, true),
+ do_lock(),
+ ...
+ ]]></code>
+ <p>
+ When ordered to shut down, the <c>gen_statem</c> then calls
+ callback function <c>terminate(shutdown, State, Data)</c>.
+ </p>
+ <p>
+ In this example, function <c>terminate/3</c>
+ locks the door if it is open, so we do not accidentally leave the door
+ open when the supervision tree terminates:
+ </p>
+ <code type="erl"><![CDATA[
+terminate(_Reason, State, _Data) ->
+ State =/= locked andalso do_lock(),
+ ok.
+ ]]></code>
+ </section>
+
+ <section>
+ <marker id="Standalone gen_statem" />
+ <title>Standalone gen_statem</title>
+ <p>
+ If the <c>gen_statem</c> is not part of a supervision tree,
+ it can be stopped using
+ <seealso marker="stdlib:gen_statem#stop/1"><c>gen_statem:stop</c></seealso>,
+ preferably through an API function:
+ </p>
+ <code type="erl"><![CDATA[
+...
+-export([start_link/1,stop/0]).
+
+...
+stop() ->
+ gen_statem:stop(?NAME).
+ ]]></code>
+ <p>
+ This makes the <c>gen_statem</c> call callback function
+ <c>terminate/3</c> just like for a supervised server
+ and waits for the process to terminate.
+ </p>
+ </section>
+ </section>
+
+<!-- =================================================================== -->
+
+ <section>
+ <marker id="Event Time-Outs" />
+ <title>Event Time-Outs</title>
+ <p>
+ A timeout feature inherited from <c>gen_statem</c>'s predecessor
+ <seealso marker="stdlib:gen_fsm"><c>gen_fsm</c></seealso>,
+ is an event time-out, that is,
+ if an event arrives the timer is cancelled.
+ You get either an event or a time-out, but not both.
+ </p>
+ <p>
+ It is ordered by the state transition action
+ <c>{timeout,Time,EventContent}</c>, or just <c>Time</c>,
+ or even just <c>Time</c> instead of an action list
+ (the latter is a form inherited from <c>gen_fsm</c>.
+ </p>
+ <p>
+ This type of time-out is useful to for example act on inactivity.
+ Let us start restart the code sequence
+ if no button is pressed for say 30 seconds:
+ </p>
+ <code type="erl"><![CDATA[
+...
+
+locked(
+ timeout, _,
+ #{code := Code, remaining := Remaining} = Data) ->
+ {next_state, locked, Data#{remaining := Code}};
+locked(
+ cast, {button,Digit},
+ #{code := Code, remaining := Remaining} = Data) ->
+...
+ [Digit|Rest] -> % Incomplete
+ {next_state, locked, Data#{remaining := Rest}, 30000};
+...
+ ]]></code>
+ <p>
+ Whenever we receive a button event we start an event timeout
+ of 30 seconds, and if we get an event type <c>timeout</c>
+ we reset the remaining code sequence.
+ </p>
+ <p>
+ An event timeout is cancelled by any other event so you either
+ get some other event or the timeout event. It is therefore
+ not possible nor needed to cancel or restart an event timeout.
+ Whatever event you act on has already cancelled
+ the event timeout...
+ </p>
+ </section>
+
+<!-- =================================================================== -->
+
+ <section>
+ <marker id="Erlang Timers" />
+ <title>Erlang Timers</title>
+ <p>
+ The previous example of state time-outs only work if
+ the state machine stays in the same state during the
+ time-out time. And event time-outs only work if no
+ disturbing unrelated events occur.
+ </p>
+ <p>
+ You may want to start a timer in one state and respond
+ to the time-out in another, maybe cancel the time-out
+ without changing states, or perhaps run multiple
+ time-outs in parallel. All this can be accomplished
+ with Erlang Timers:
+ <seealso marker="erts:erlang#start_timer/4"><c>erlang:start_timer3,4</c></seealso>.
+ </p>
+ <p>
+ Here is how to accomplish the state time-out
+ in the previous example by insted using an Erlang Timer:
+ </p>
+ <code type="erl"><![CDATA[
+...
+locked(
+ cast, {button,Digit},
+ #{code := Code, remaining := Remaining} = Data) ->
+ case Remaining of
+ [Digit] ->
+ do_unlock(),
+ Tref = erlang:start_timer(10000, self(), lock),
+ {next_state, open, Data#{remaining := Code, timer => Tref}};
+...
+
+open(info, {timeout,Tref,lock}, #{timer := Tref} = Data) ->
+ do_lock(),
+ {next_state,locked,maps:remove(timer, Data)};
+open(cast, {button,_}, Data) ->
+ {keep_state,Data};
+...
+ ]]></code>
+ <p>
+ Removing the <c>timer</c> key from the map when we
+ change to state <c>locked</c> is not strictly
+ necessary since we can only get into state <c>open</c>
+ with an updated <c>timer</c> map value. But it can be nice
+ to not have outdated values in the state <c>Data</c>!
+ </p>
+ <p>
+ If you need to cancel a timer because of some other event, you can use
+ <seealso marker="erts:erlang#cancel_timer/2"><c>erlang:cancel_timer(Tref)</c></seealso>.
+ Note that a time-out message cannot arrive after this,
+ unless you have postponed it before (see the next section),
+ so ensure that you do not accidentally postpone such messages.
+ Also note that a time-out message may have arrived
+ just before you cancelling it, so you may have to read out
+ such a message from the process mailbox depending on
+ the return value from
+ <seealso marker="erts:erlang#cancel_timer/2"><c>erlang:cancel_timer(Tref)</c></seealso>.
+ </p>
+ <p>
+ Another way to handle a late time-out can be to not cancel it,
+ but to ignore it if it arrives in a state
+ where it is known to be late.
+ </p>
+ </section>
+
+<!-- =================================================================== -->
+
+ <section>
+ <marker id="Postponing Events" />
+ <title>Postponing Events</title>
+ <p>
+ If you want to ignore a particular event in the current state
+ and handle it in a future state, you can postpone the event.
+ A postponed event is retried after the state has
+ changed, that is, <c>OldState =/= NewState</c>.
+ </p>
+ <p>
+ Postponing is ordered by the state transition
+ <seealso marker="stdlib:gen_statem#type-action">action</seealso>
+ <c>postpone</c>.
+ </p>
+ <p>
+ In this example, instead of ignoring button events
+ while in the <c>open</c> state, we can postpone them
+ and they are queued and later handled in the <c>locked</c> state:
+ </p>
+ <code type="erl"><![CDATA[
+...
+open(cast, {button,_}, Data) ->
+ {keep_state,Data,[postpone]};
+...
+ ]]></code>
+ <p>
+ Since a postponed event is only retried after a state change,
+ you have to think about where to keep a state data item.
+ You can keep it in the server <c>Data</c>
+ or in the <c>State</c> itself,
+ for example by having two more or less identical states
+ to keep a boolean value, or by using a complex state with
+ <seealso marker="#Callback Modes">callback mode</seealso>
+ <seealso marker="stdlib:gen_statem#type-callback_mode"><c>handle_event_function</c></seealso>.
+ If a change in the value changes the set of events that is handled,
+ then the value should be kept in the State.
+ Otherwise no postponed events will be retried
+ since only the server Data changes.
+ </p>
+ <p>
+ This is not important if you do not postpone events.
+ But if you later decide to start postponing some events,
+ then the design flaw of not having separate states
+ when they should be, might become a hard to find bug.
+ </p>
+
+ <section>
+ <marker id="Fuzzy State Diagrams" />
+ <title>Fuzzy State Diagrams</title>
+ <p>
+ It is not uncommon that a state diagram does not specify
+ how to handle events that are not illustrated
+ in a particular state in the diagram.
+ Hopefully this is described in an associated text
+ or from the context.
+ </p>
+ <p>
+ Possible actions: ignore as in drop the event
+ (maybe log it) or deal with the event in some other state
+ as in postpone it.
+ </p>
+ </section>
+
+ <section>
+ <marker id="Selective Receive" />
+ <title>Selective Receive</title>
+ <p>
+ Erlang's selective receive statement is often used to
+ describe simple state machine examples in straightforward
+ Erlang code. The following is a possible implementation of
+ the first example:
+ </p>
+ <code type="erl"><![CDATA[
+-module(code_lock).
+-define(NAME, code_lock_1).
+-export([start_link/1,button/1]).
+
+start_link(Code) ->
+ spawn(
+ fun () ->
+ true = register(?NAME, self()),
+ do_lock(),
+ locked(Code, Code)
+ end).
+
+button(Digit) ->
+ ?NAME ! {button,Digit}.
+
+locked(Code, [Digit|Remaining]) ->
+ receive
+ {button,Digit} when Remaining =:= [] ->
+ do_unlock(),
+ open(Code);
+ {button,Digit} ->
+ locked(Code, Remaining);
+ {button,_} ->
+ locked(Code, Code)
+ end.
+
+open(Code) ->
+ receive
+ after 10000 ->
+ do_lock(),
+ locked(Code, Code)
+ end.
+
+do_lock() ->
+ io:format("Locked~n", []).
+do_unlock() ->
+ io:format("Open~n", []).
+ ]]></code>
+ <p>
+ The selective receive in this case causes implicitly <c>open</c>
+ to postpone any events to the <c>locked</c> state.
+ </p>
+ <p>
+ A selective receive cannot be used from a <c>gen_statem</c>
+ behavior as for any <c>gen_*</c> behavior,
+ as the receive statement is within the <c>gen_*</c> engine itself.
+ It must be there because all
+ <seealso marker="stdlib:sys"><c>sys</c></seealso>
+ compatible behaviors must respond to system messages and therefore
+ do that in their engine receive loop,
+ passing non-system messages to the callback module.
+ </p>
+ <p>
+ The state transition
+ <seealso marker="stdlib:gen_statem#type-action">action</seealso>
+ <c>postpone</c> is designed to model
+ selective receives. A selective receive implicitly postpones
+ any not received events, but the <c>postpone</c>
+ state transition action explicitly postpones one received event.
+ </p>
+ <p>
+ Both mechanisms have the same theoretical
+ time and memory complexity, while the selective receive
+ language construct has smaller constant factors.
+ </p>
+ </section>
+ </section>
+
+<!-- =================================================================== -->
+
+ <section>
+ <marker id="State Entry Actions" />
+ <title>State Entry Actions</title>
+ <p>
+ Say you have a state machine specification
+ that uses state entry actions.
+ Allthough you can code this using self-generated events
+ (described in the next section), especially if just
+ one or a few states has got state entry actions,
+ this is a perfect use case for the built in
+ <seealso marker="#State Enter Calls">state enter calls</seealso>.
+ </p>
+ <p>
+ You return a list containing <c>state_enter</c> from your
+ <seealso marker="stdlib:gen_statem#Module:callback_mode/0"><c>callback_mode/0</c></seealso>
+ function and the <c>gen_statem</c> engine will call your
+ state callback once with the arguments
+ <c>(enter, OldState, ...)</c> whenever the state changes.
+ Then you just need to handle these event-like calls in all states.
+ </p>
+ <code type="erl"><![CDATA[
+...
+init(Code) ->
+ process_flag(trap_exit, true),
+ Data = #{code => Code},
+ {ok, locked, Data}.
+
+callback_mode() ->
+ [state_functions,state_enter].
+
+locked(enter, _OldState, Data) ->
+ do_lock(),
+ {keep_state,Data#{remaining => Code}};
+locked(
+ cast, {button,Digit},
+ #{code := Code, remaining := Remaining} = Data) ->
+ case Remaining of
+ [Digit] ->
+ {next_state, open, Data};
+...
+
+open(enter, _OldState, _Data) ->
+ do_unlock(),
+ {keep_state_and_data, [{state_timeout,10000,lock}]};
+open(state_timeout, lock, Data) ->
+ {next_state, locked, Data};
+...
+ ]]></code>
+ </section>
+
+<!-- =================================================================== -->
+
+ <section>
+ <marker id="Self-Generated Events" />
+ <title>Self-Generated Events</title>
+ <p>
+ It can sometimes be beneficial to be able to generate events
+ to your own state machine.
+ This can be done with the state transition
+ <seealso marker="stdlib:gen_statem#type-action">action</seealso>
+ <c>{next_event,EventType,EventContent}</c>.
+ </p>
+ <p>
+ You can generate events of any existing
+ <seealso marker="stdlib:gen_statem#type-action">type</seealso>,
+ but the <c>internal</c> type can only be generated through action
+ <c>next_event</c>. Hence, it cannot come from an external source,
+ so you can be certain that an <c>internal</c> event is an event
+ from your state machine to itself.
+ </p>
+ <p>
+ One example for this is to pre-process incoming data, for example
+ decrypting chunks or collecting characters up to a line break.
+ Purists may argue that this should be modelled with a separate
+ state machine that sends pre-processed events
+ to the main state machine.
+ But to decrease overhead the small pre-processing state machine
+ can be implemented in the common state event handling
+ of the main state machine using a few state data variables
+ that then sends the pre-processed events as internal events
+ to the main state machine.
+ </p>
+ <p>
+ The following example uses an input model where you give the lock
+ characters with <c>put_chars(Chars)</c> and then call
+ <c>enter()</c> to finish the input.
+ </p>
+ <code type="erl"><![CDATA[
+...
+-export(put_chars/1, enter/0).
+...
+put_chars(Chars) when is_binary(Chars) ->
+ gen_statem:call(?NAME, {chars,Chars}).
+
+enter() ->
+ gen_statem:call(?NAME, enter).
+
+...
+
+locked(enter, _OldState, Data) ->
+ do_lock(),
+ {keep_state,Data#{remaining => Code, buf => []}};
+...
+
+handle_event({call,From}, {chars,Chars}, #{buf := Buf} = Data) ->
+ {keep_state, Data#{buf := [Chars|Buf],
+ [{reply,From,ok}]};
+handle_event({call,From}, enter, #{buf := Buf} = Data) ->
+ Chars = unicode:characters_to_binary(lists:reverse(Buf)),
+ try binary_to_integer(Chars) of
+ Digit ->
+ {keep_state, Data#{buf := []},
+ [{reply,From,ok},
+ {next_event,internal,{button,Chars}}]}
+ catch
+ error:badarg ->
+ {keep_state, Data#{buf := []},
+ [{reply,From,{error,not_an_integer}}]}
+ end;
+...
+ ]]></code>
+ <p>
+ If you start this program with <c>code_lock:start([17])</c>
+ you can unlock with <c>code_lock:put_chars(&lt;&lt;"001">>),
+ code_lock:put_chars(&lt;&lt;"7">>), code_lock:enter()</c>.
+ </p>
+ </section>
+
+<!-- =================================================================== -->
+
+ <section>
+ <marker id="Example Revisited" />
+ <title>Example Revisited</title>
+ <p>
+ This section includes the example after most of the mentioned
+ modifications and some more using state enter calls,
+ which deserves a new state diagram:
+ </p>
+ <image file="../design_principles/code_lock_2.png">
+ <icaption>Code Lock State Diagram Revisited</icaption>
+ </image>
+ <p>
+ Notice that this state diagram does not specify how to handle
+ a button event in the state <c>open</c>. So, you need to
+ read somewhere else that unspecified events
+ must be ignored as in not consumed but handled in some other state.
+ Also, the state diagram does not show that the <c>code_length/0</c>
+ call must be handled in every state.
+ </p>
+
+ <section>
+ <marker id="Callback Mode: state_functions" />
+ <title>Callback Mode: state_functions</title>
+ <p>
+ Using state functions:
+ </p>
+ <code type="erl"><![CDATA[
+-module(code_lock).
+-behaviour(gen_statem).
+-define(NAME, code_lock_2).
+
+-export([start_link/1,stop/0]).
+-export([button/1,code_length/0]).
+-export([init/1,callback_mode/0,terminate/3,code_change/4]).
+-export([locked/3,open/3]).
+
+start_link(Code) ->
+ gen_statem:start_link({local,?NAME}, ?MODULE, Code, []).
+stop() ->
+ gen_statem:stop(?NAME).
+
+button(Digit) ->
+ gen_statem:cast(?NAME, {button,Digit}).
+code_length() ->
+ gen_statem:call(?NAME, code_length).
+
+init(Code) ->
+ process_flag(trap_exit, true),
+ Data = #{code => Code},
+ {ok, locked, Data}.
+
+callback_mode() ->
+ [state_functions,state_enter].
+
+locked(enter, _OldState, #{code := Code} = Data) ->
+ do_lock(),
+ {keep_state, Data#{remaining => Code}};
+locked(
+ timeout, _,
+ #{code := Code, remaining := Remaining} = Data) ->
+ {keep_state, Data#{remaining := Code}};
+locked(
+ cast, {button,Digit},
+ #{code := Code, remaining := Remaining} = Data) ->
+ case Remaining of
+ [Digit] -> % Complete
+ {next_state, open, Data};
+ [Digit|Rest] -> % Incomplete
+ {keep_state, Data#{remaining := Rest}, 30000};
+ [_|_] -> % Wrong
+ {keep_state, Data#{remaining := Code}}
+ end;
+locked(EventType, EventContent, Data) ->
+ handle_event(EventType, EventContent, Data).
+
+open(enter, _OldState, _Data) ->
+ do_unlock(),
+ {keep_state_and_data, [{state_timeout,10000,lock}]};
+open(state_timeout, lock, Data) ->
+ {next_state, locked, Data};
+open(cast, {button,_}, _) ->
+ {keep_state_and_data, [postpone]};
+open(EventType, EventContent, Data) ->
+ handle_event(EventType, EventContent, Data).
+
+handle_event({call,From}, code_length, #{code := Code}) ->
+ {keep_state_and_data, [{reply,From,length(Code)}]}.
+
+do_lock() ->
+ io:format("Locked~n", []).
+do_unlock() ->
+ io:format("Open~n", []).
+
+terminate(_Reason, State, _Data) ->
+ State =/= locked andalso do_lock(),
+ ok.
+code_change(_Vsn, State, Data, _Extra) ->
+ {ok,State,Data}.
+ ]]></code>
+ </section>
+
+ <section>
+ <marker id="Callback Mode: handle_event_function" />
+ <title>Callback Mode: handle_event_function</title>
+ <p>
+ This section describes what to change in the example
+ to use one <c>handle_event/4</c> function.
+ The previously used approach to first branch depending on event
+ does not work that well here because of the state enter calls,
+ so this example first branches depending on state:
+ </p>
+ <code type="erl"><![CDATA[
+...
+-export([handle_event/4]).
+
+...
+callback_mode() ->
+ [handle_event_function,state_enter].
+
+%% State: locked
+handle_event(
+ enter, _OldState, locked,
+ #{code := Code} = Data) ->
+ do_lock(),
+ {keep_state, Data#{remaining => Code}};
+handle_event(
+ timeout, _, locked,
+ #{code := Code, remaining := Remaining} = Data) ->
+ {keep_state, Data#{remaining := Code}};
+handle_event(
+ cast, {button,Digit}, locked,
+ #{code := Code, remaining := Remaining} = Data) ->
+ case Remaining of
+ [Digit] -> % Complete
+ {next_state, open, Data};
+ [Digit|Rest] -> % Incomplete
+ {keep_state, Data#{remaining := Rest}, 30000};
+ [_|_] -> % Wrong
+ {keep_state, Data#{remaining := Code}}
+ end;
+%%
+%% State: open
+handle_event(enter, _OldState, open, _Data) ->
+ do_unlock(),
+ {keep_state_and_data, [{state_timeout,10000,lock}]};
+handle_event(state_timeout, lock, open, Data) ->
+ {next_state, locked, Data};
+handle_event(cast, {button,_}, open, _) ->
+ {keep_state_and_data,[postpone]};
+%%
+%% Any state
+handle_event({call,From}, code_length, _State, #{code := Code}) ->
+ {keep_state_and_data, [{reply,From,length(Code)}]}.
+
+...
+ ]]></code>
+ </section>
+ <p>
+ Notice that postponing buttons from the <c>locked</c> state
+ to the <c>open</c> state feels like a strange thing to do
+ for a code lock, but it at least illustrates event postponing.
+ </p>
+ </section>
+
+<!-- =================================================================== -->
+
+ <section>
+ <marker id="Filter the State" />
+ <title>Filter the State</title>
+ <p>
+ The example servers so far in this chapter
+ print the full internal state in the error log, for example,
+ when killed by an exit signal or because of an internal error.
+ This state contains both the code lock code
+ and which digits that remain to unlock.
+ </p>
+ <p>
+ This state data can be regarded as sensitive,
+ and maybe not what you want in the error log
+ because of some unpredictable event.
+ </p>
+ <p>
+ Another reason to filter the state can be
+ that the state is too large to print, as it fills
+ the error log with uninteresting details.
+ </p>
+ <p>
+ To avoid this, you can format the internal state
+ that gets in the error log and gets returned from
+ <seealso marker="stdlib:sys#get_status/1"><c>sys:get_status/1,2</c></seealso>
+ by implementing function
+ <seealso marker="stdlib:gen_statem#Module:format_status/2"><c>Module:format_status/2</c></seealso>,
+ for example like this:
+ </p>
+ <code type="erl"><![CDATA[
+...
+-export([init/1,terminate/3,code_change/4,format_status/2]).
+...
+
+format_status(Opt, [_PDict,State,Data]) ->
+ StateData =
+ {State,
+ maps:filter(
+ fun (code, _) -> false;
+ (remaining, _) -> false;
+ (_, _) -> true
+ end,
+ Data)},
+ case Opt of
+ terminate ->
+ StateData;
+ normal ->
+ [{data,[{"State",StateData}]}]
+ end.
+ ]]></code>
+ <p>
+ It is not mandatory to implement a
+ <seealso marker="stdlib:gen_statem#Module:format_status/2"><c>Module:format_status/2</c></seealso>
+ function. If you do not, a default implementation is used that
+ does the same as this example function without filtering
+ the <c>Data</c> term, that is, <c>StateData = {State,Data}</c>,
+ in this example containing sensitive information.
+ </p>
+ </section>
+
+<!-- =================================================================== -->
+
+ <section>
+ <marker id="Complex State" />
+ <title>Complex State</title>
+ <p>
+ The callback mode
+ <seealso marker="stdlib:gen_statem#type-callback_mode"><c>handle_event_function</c></seealso>
+ enables using a non-atom state as described in section
+ <seealso marker="#Callback Modes">Callback Modes</seealso>,
+ for example, a complex state term like a tuple.
+ </p>
+ <p>
+ One reason to use this is when you have
+ a state item that affects the event handling,
+ in particular in combination with postponing events.
+ We complicate the previous example
+ by introducing a configurable lock button
+ (this is the state item in question),
+ which in the <c>open</c> state immediately locks the door,
+ and an API function <c>set_lock_button/1</c> to set the lock button.
+ </p>
+ <p>
+ Suppose now that we call <c>set_lock_button</c>
+ while the door is open,
+ and have already postponed a button event
+ that until now was not the lock button.
+ The sensible thing can be to say that
+ the button was pressed too early so it is
+ not to be recognized as the lock button.
+ However, then it can be surprising that a button event
+ that now is the lock button event arrives (as retried postponed)
+ immediately after the state transits to <c>locked</c>.
+ </p>
+ <p>
+ So we make the <c>button/1</c> function synchronous
+ by using
+ <seealso marker="stdlib:gen_statem#call/2"><c>gen_statem:call</c></seealso>
+ and still postpone its events in the <c>open</c> state.
+ Then a call to <c>button/1</c> during the <c>open</c>
+ state does not return until the state transits to <c>locked</c>,
+ as it is there the event is handled and the reply is sent.
+ </p>
+ <p>
+ If a process now calls <c>set_lock_button/1</c>
+ to change the lock button while another process
+ hangs in <c>button/1</c> with the new lock button,
+ it can be expected that the hanging lock button call
+ immediately takes effect and locks the lock.
+ Therefore, we make the current lock button a part of the state,
+ so that when we change the lock button, the state changes
+ and all postponed events are retried.
+ </p>
+ <p>
+ We define the state as <c>{StateName,LockButton}</c>,
+ where <c>StateName</c> is as before
+ and <c>LockButton</c> is the current lock button:
+ </p>
+ <code type="erl"><![CDATA[
+-module(code_lock).
+-behaviour(gen_statem).
+-define(NAME, code_lock_3).
+
+-export([start_link/2,stop/0]).
+-export([button/1,code_length/0,set_lock_button/1]).
+-export([init/1,callback_mode/0,terminate/3,code_change/4,format_status/2]).
+-export([handle_event/4]).
+
+start_link(Code, LockButton) ->
+ gen_statem:start_link(
+ {local,?NAME}, ?MODULE, {Code,LockButton}, []).
+stop() ->
+ gen_statem:stop(?NAME).
+
+button(Digit) ->
+ gen_statem:call(?NAME, {button,Digit}).
+code_length() ->
+ gen_statem:call(?NAME, code_length).
+set_lock_button(LockButton) ->
+ gen_statem:call(?NAME, {set_lock_button,LockButton}).
+
+init({Code,LockButton}) ->
+ process_flag(trap_exit, true),
+ Data = #{code => Code, remaining => undefined},
+ {ok, {locked,LockButton}, Data}.
+
+callback_mode() ->
+ [handle_event_function,state_enter].
+
+handle_event(
+ {call,From}, {set_lock_button,NewLockButton},
+ {StateName,OldLockButton}, Data) ->
+ {next_state, {StateName,NewLockButton}, Data,
+ [{reply,From,OldLockButton}]};
+handle_event(
+ {call,From}, code_length,
+ {_StateName,_LockButton}, #{code := Code}) ->
+ {keep_state_and_data,
+ [{reply,From,length(Code)}]};
+%%
+%% State: locked
+handle_event(
+ EventType, EventContent,
+ {locked,LockButton}, #{code := Code, remaining := Remaining} = Data) ->
+ case {EventType, EventContent} of
+ {enter, _OldState} ->
+ do_lock(),
+ {keep_state, Data#{remaining := Code}};
+ {timeout, _} ->
+ {keep_state, Data#{remaining := Code}};
+ {{call,From}, {button,Digit}} ->
+ case Remaining of
+ [Digit] -> % Complete
+ {next_state, {open,LockButton}, Data,
+ [{reply,From,ok}]};
+ [Digit|Rest] -> % Incomplete
+ {keep_state, Data#{remaining := Rest, 30000},
+ [{reply,From,ok}]};
+ [_|_] -> % Wrong
+ {keep_state, Data#{remaining := Code},
+ [{reply,From,ok}]}
+ end
+ end;
+%%
+%% State: open
+handle_event(
+ EventType, EventContent,
+ {open,LockButton}, Data) ->
+ case {EventType, EventContent} of
+ {enter, _OldState} ->
+ do_unlock(),
+ {keep_state_and_data, [{state_timeout,10000,lock}]};
+ {state_timeout, lock} ->
+ {next_state, {locked,LockButton}, Data};
+ {{call,From}, {button,Digit}} ->
+ if
+ Digit =:= LockButton ->
+ {next_state, {locked,LockButton}, Data,
+ [{reply,From,locked}]);
+ true ->
+ {keep_state_and_data,
+ [postpone]}
+ end
+ end.
+
+do_lock() ->
+ io:format("Locked~n", []).
+do_unlock() ->
+ io:format("Open~n", []).
+
+terminate(_Reason, State, _Data) ->
+ State =/= locked andalso do_lock(),
+ ok.
+code_change(_Vsn, State, Data, _Extra) ->
+ {ok,State,Data}.
+format_status(Opt, [_PDict,State,Data]) ->
+ StateData =
+ {State,
+ maps:filter(
+ fun (code, _) -> false;
+ (remaining, _) -> false;
+ (_, _) -> true
+ end,
+ Data)},
+ case Opt of
+ terminate ->
+ StateData;
+ normal ->
+ [{data,[{"State",StateData}]}]
+ end.
+ ]]></code>
+ <p>
+ It can be an ill-fitting model for a physical code lock
+ that the <c>button/1</c> call can hang until the lock
+ is locked. But for an API in general it is not that strange.
+ </p>
+ </section>
+
+<!-- =================================================================== -->
+
+ <section>
+ <marker id="Hibernation" />
+ <title>Hibernation</title>
+ <p>
+ If you have many servers in one node
+ and they have some state(s) in their lifetime in which
+ the servers can be expected to idle for a while,
+ and the amount of heap memory all these servers need
+ is a problem, then the memory footprint of a server
+ can be mimimized by hibernating it through
+ <seealso marker="stdlib:proc_lib#hibernate/3"><c>proc_lib:hibernate/3</c></seealso>.
+ </p>
+ <note>
+ <p>
+ It is rather costly to hibernate a process; see
+ <seealso marker="erts:erlang#hibernate/3"><c>erlang:hibernate/3</c></seealso>.
+ It is not something you want to do after every event.
+ </p>
+ </note>
+ <p>
+ We can in this example hibernate in the <c>{open,_}</c> state,
+ because what normally occurs in that state is that
+ the state time-out after a while
+ triggers a transition to <c>{locked,_}</c>:
+ </p>
+ <code type="erl"><![CDATA[
+...
+%% State: open
+handle_event(
+ EventType, EventContent,
+ {open,LockButton}, Data) ->
+ case {EventType, EventContent} of
+ {enter, _OldState} ->
+ do_unlock(),
+ {keep_state_and_data,
+ [{state_timeout,10000,lock},hibernate]};
+...
+ ]]></code>
+ <p>
+ The atom
+ <seealso marker="stdlib:gen_statem#type-hibernate"><c>hibernate</c></seealso>
+ in the action list on the last line
+ when entering the <c>{open,_}</c> state is the only change.
+ If any event arrives in the <c>{open,_},</c> state, we
+ do not bother to rehibernate, so the server stays
+ awake after any event.
+ </p>
+ <p>
+ To change that we would need to insert
+ action <c>hibernate</c> in more places.
+ For example, for the state-independent <c>set_lock_button</c>
+ and <c>code_length</c> operations that then would have to
+ be aware of using <c>hibernate</c> while in the
+ <c>{open,_}</c> state, which would clutter the code.
+ </p>
+ <p>
+ Another not uncommon scenario is to use the event time-out
+ to triger hibernation after a certain time of inactivity.
+ </p>
+ <p>
+ This server probably does not use
+ heap memory worth hibernating for.
+ To gain anything from hibernation, your server would
+ have to produce some garbage during callback execution,
+ for which this example server can serve as a bad example.
+ </p>
+ </section>
+
+</chapter>
diff --git a/system/doc/design_principles/sup_princ.xml b/system/doc/design_principles/sup_princ.xml
index 5e2f6ba9cb..0a24e97950 100644
--- a/system/doc/design_principles/sup_princ.xml
+++ b/system/doc/design_principles/sup_princ.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2014</year>
+ <year>1997</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -80,8 +80,8 @@ init(_Args) ->
</section>
<section>
- <title>Supervisor Flags</title>
<marker id="flags"/>
+ <title>Supervisor Flags</title>
<p>This is the type definition for the supervisor flags:</p>
<code type="none"><![CDATA[
sup_flags() = #{strategy => strategy(), % optional
@@ -106,9 +106,8 @@ sup_flags() = #{strategy => strategy(), % optional
</section>
<section>
- <marker id="strategy"></marker>
+ <marker id="strategy"/>
<title>Restart Strategy</title>
-
<p> The restart strategy is specified by
the <c>strategy</c> key in the supervisor flags map returned by
the callback function <c>init</c>:</p>
@@ -213,6 +212,7 @@ child_spec() = #{id => child_id(), % mandatory
<item><c>supervisor:start_link</c></item>
<item><c>gen_server:start_link</c></item>
<item><c>gen_fsm:start_link</c></item>
+ <item><c>gen_statem:start_link</c></item>
<item><c>gen_event:start_link</c></item>
<item>A function compliant with these functions. For details,
see the <c>supervisor(3)</c> manual page.</item>
@@ -229,7 +229,7 @@ child_spec() = #{id => child_id(), % mandatory
is <c>rest_for_one</c> or <c>one_for_all</c> and a sibling
death causes the temporary process to be terminated).</item>
<item>A <c>transient</c> child process is restarted only if it
- terminates abnormally, that is, with another exit reason than
+ terminates abnormally, that is, with an exit reason other than
<c>normal</c>, <c>shutdown</c>, or <c>{shutdown,Term}</c>.</item>
</list>
<p>The <c>restart</c> key is optional. If it is not given, the
@@ -276,7 +276,8 @@ child_spec() = #{id => child_id(), % mandatory
<p><c>modules</c> are to be a list with one element
<c>[Module]</c>, where <c>Module</c> is the name of
the callback module, if the child process is a supervisor,
- gen_server or gen_fsm. If the child process is a gen_event,
+ gen_server, gen_fsm or gen_statem.
+ If the child process is a gen_event,
the value shall be <c>dynamic</c>.</p>
<p>This information is used by the release handler during
upgrades and downgrades, see
@@ -400,8 +401,8 @@ supervisor:delete_child(Sup, Id)</code>
restarts.</p>
</section>
- <marker id="simple"/>
<section>
+ <marker id="simple"/>
<title>Simplified one_for_one Supervisors</title>
<p>A supervisor with restart strategy <c>simple_one_for_one</c> is
a simplified <c>one_for_one</c> supervisor, where all child
diff --git a/system/doc/design_principles/xmlfiles.mk b/system/doc/design_principles/xmlfiles.mk
index 3032ac3ab9..e476255d62 100644
--- a/system/doc/design_principles/xmlfiles.mk
+++ b/system/doc/design_principles/xmlfiles.mk
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2009. All Rights Reserved.
+# Copyright Ericsson AB 2009-2016. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@ DESIGN_PRINCIPLES_CHAPTER_FILES = \
distributed_applications.xml \
events.xml \
fsm.xml \
+ statem.xml \
gen_server_concepts.xml \
included_applications.xml \
release_handling.xml \
diff --git a/system/doc/efficiency_guide/Makefile b/system/doc/efficiency_guide/Makefile
index 0665bb91f7..36e4cd00df 100644
--- a/system/doc/efficiency_guide/Makefile
+++ b/system/doc/efficiency_guide/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2001-2012. All Rights Reserved.
+# Copyright Ericsson AB 2001-2016. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/system/doc/efficiency_guide/advanced.xml b/system/doc/efficiency_guide/advanced.xml
index d4e47f4f10..eee2648f34 100644
--- a/system/doc/efficiency_guide/advanced.xml
+++ b/system/doc/efficiency_guide/advanced.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2001</year><year>2013</year>
+ <year>2001</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -35,8 +35,7 @@
how much memory different data types and operations require. It is
implementation-dependent how much memory the Erlang data types and
other items consume, but the following table shows some figures for
- the <c>erts-5.2</c> system in R9B. There have been no significant
- changes in R13.</p>
+ the <c>erts-8.0</c> system in OTP 19.0.</p>
<p>The unit of measurement is memory words. There exists both a
32-bit and a 64-bit implementation. A word is therefore 4 bytes or
@@ -87,6 +86,19 @@
<cell>2 words + the size of each element.</cell>
</row>
<row>
+ <cell>Small Map</cell>
+ <cell>4 words + 2 words per entry (key and value) + the size of each key and value pair.</cell>
+ </row>
+ <row>
+ <cell>Large Map</cell>
+ <cell>
+ At least, 2 words + 2 x <c>N</c> words + 2 x log16(<c>N</c>) words +
+ the size of each key and value pair, where <c>N</c> is the number of pairs in the Map.
+ A large Map is represented as a tree internally where each node in the tree is a
+ "sparse tuple" of arity 16.
+ </cell>
+ </row>
+ <row>
<cell>Pid</cell>
<cell>1 word for a process identifier from the current local node
+ 5 words for a process identifier from another node.<br></br>
@@ -122,7 +134,7 @@
</row>
<row>
<cell>Erlang process</cell>
- <cell>327 words when spawned, including a heap of 233 words.</cell>
+ <cell>338 words when spawned, including a heap of 233 words.</cell>
</row>
<tcaption>Memory Size of Different Data Types</tcaption>
</table>
@@ -144,7 +156,7 @@
<seealso marker="erts:erl#max_processes"><c>+P</c></seealso>
command-line flag in the
<seealso marker="erts:erl"><c>erl(1)</c></seealso>
- manual page in <c>erts</c>.</cell>
+ manual page in ERTS.</cell>
</row>
<row>
<cell>Known nodes</cell>
@@ -224,7 +236,7 @@
<seealso marker="erts:erl#max_ports"><c>+Q</c></seealso>
command-line flag in the
<seealso marker="erts:erl"><c>erl(1)</c></seealso> manual page
- in <c>erts</c>.</cell>
+ in ERTS.</cell>
</row>
<row>
<cell><marker id="files_sockets"></marker>Open files and
diff --git a/system/doc/efficiency_guide/appendix.xml b/system/doc/efficiency_guide/appendix.xml
index 1e2e906515..225c8c4e2f 100644
--- a/system/doc/efficiency_guide/appendix.xml
+++ b/system/doc/efficiency_guide/appendix.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2002</year>
- <year>2013</year>
+ <year>2016</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/efficiency_guide/binaryhandling.xml b/system/doc/efficiency_guide/binaryhandling.xml
index 51f8c4ebf0..0295d18644 100644
--- a/system/doc/efficiency_guide/binaryhandling.xml
+++ b/system/doc/efficiency_guide/binaryhandling.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2007</year>
- <year>2014</year>
+ <year>2016</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -190,15 +190,15 @@ Bin4 = <<Bin1/binary,17>>, %% 5 !!!
its size set to the size of the data stored in the binary, while
the binary object has extra space allocated.
The size of the binary object is either twice the
- size of <c>Bin0</c> or 256, whichever is larger. In this case
+ size of <c>Bin1</c> or 256, whichever is larger. In this case
it is 256.</item>
<item>Line 3 is more interesting.
<c>Bin1</c> <em>has</em> been used in an append operation,
- and it has 255 bytes of unused storage at the end, so the 3 new
+ and it has 252 bytes of unused storage at the end, so the 3 new
bytes are stored there.</item>
- <item>Line 4. The same applies here. There are 252 bytes left,
+ <item>Line 4. The same applies here. There are 249 bytes left,
so there is no problem storing another 3 bytes.</item>
<item>Line 5. Here, something <em>interesting</em> happens. Notice
diff --git a/system/doc/efficiency_guide/book.xml b/system/doc/efficiency_guide/book.xml
index 76f0ad24d3..e3d6fd5fc2 100644
--- a/system/doc/efficiency_guide/book.xml
+++ b/system/doc/efficiency_guide/book.xml
@@ -4,7 +4,7 @@
<book xmlns:xi="http://www.w3.org/2001/XInclude">
<header titlestyle="normal">
<copyright>
- <year>2001</year><year>2013</year>
+ <year>2001</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/efficiency_guide/commoncaveats.xml b/system/doc/efficiency_guide/commoncaveats.xml
index c1d71e745a..ecfeff0349 100644
--- a/system/doc/efficiency_guide/commoncaveats.xml
+++ b/system/doc/efficiency_guide/commoncaveats.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2001</year><year>2013</year>
+ <year>2001</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/efficiency_guide/drivers.xml b/system/doc/efficiency_guide/drivers.xml
index 202551ab8e..c99701eeba 100644
--- a/system/doc/efficiency_guide/drivers.xml
+++ b/system/doc/efficiency_guide/drivers.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2009</year><year>2013</year>
+ <year>2009</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/efficiency_guide/functions.xml b/system/doc/efficiency_guide/functions.xml
index 9616df554e..4a8248e65c 100644
--- a/system/doc/efficiency_guide/functions.xml
+++ b/system/doc/efficiency_guide/functions.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2001</year><year>2013</year>
+ <year>2001</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/efficiency_guide/introduction.xml b/system/doc/efficiency_guide/introduction.xml
index 121ce3af21..ca4a41c798 100644
--- a/system/doc/efficiency_guide/introduction.xml
+++ b/system/doc/efficiency_guide/introduction.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2001</year><year>2013</year>
+ <year>2001</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/efficiency_guide/listhandling.xml b/system/doc/efficiency_guide/listhandling.xml
index c7b5cf9a9a..2ebc877820 100644
--- a/system/doc/efficiency_guide/listhandling.xml
+++ b/system/doc/efficiency_guide/listhandling.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2001</year><year>2013</year>
+ <year>2001</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/efficiency_guide/myths.xml b/system/doc/efficiency_guide/myths.xml
index 651d909834..5d3ad78b23 100644
--- a/system/doc/efficiency_guide/myths.xml
+++ b/system/doc/efficiency_guide/myths.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2007</year>
- <year>2013</year>
+ <year>2016</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/efficiency_guide/part.xml b/system/doc/efficiency_guide/part.xml
index 2862058bf2..6e10a0c031 100644
--- a/system/doc/efficiency_guide/part.xml
+++ b/system/doc/efficiency_guide/part.xml
@@ -4,7 +4,7 @@
<part xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>2001</year><year>2013</year>
+ <year>2001</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/efficiency_guide/processes.xml b/system/doc/efficiency_guide/processes.xml
index 2d486ef7ff..f2d9712f51 100644
--- a/system/doc/efficiency_guide/processes.xml
+++ b/system/doc/efficiency_guide/processes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2001</year><year>2013</year>
+ <year>2001</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/efficiency_guide/profiling.xml b/system/doc/efficiency_guide/profiling.xml
index 4fbec927f4..bf50a03fa6 100644
--- a/system/doc/efficiency_guide/profiling.xml
+++ b/system/doc/efficiency_guide/profiling.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2001</year><year>2013</year>
+ <year>2001</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -128,7 +128,7 @@
performance impact. Using <c>fprof</c> is just a matter of
calling a few library functions, see the
<seealso marker="tools:fprof">fprof</seealso> manual page in
- <c>tools</c> .<c>fprof</c> was introduced in R8.</p>
+ Tools .<c>fprof</c> was introduced in R8.</p>
</section>
<section>
@@ -138,7 +138,7 @@
and in which function calls this time has been spent. Time is
shown as percentage of total time and absolute time. For more
information, see the <seealso marker="tools:eprof">eprof</seealso>
- manual page in <c>tools</c>.</p>
+ manual page in Tools.</p>
</section>
<section>
@@ -152,7 +152,7 @@
optimization. Using <c>cover</c> is just a matter of calling a
few library functions, see the
<seealso marker="tools:cover">cover</seealso> manual page in
- <c>tools</c>.</p>
+ Tools.</p>
</section>
<section>
@@ -165,7 +165,7 @@
any modules to profile (compared with <c>cover</c>).
For more information, see the
<seealso marker="tools:cprof">cprof</seealso> manual page in
- <c>tools</c>.</p>
+ Tools.</p>
</section>
<section>
diff --git a/system/doc/efficiency_guide/tablesDatabases.xml b/system/doc/efficiency_guide/tablesDatabases.xml
index 865c46bc33..3f77151e55 100644
--- a/system/doc/efficiency_guide/tablesDatabases.xml
+++ b/system/doc/efficiency_guide/tablesDatabases.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2001</year><year>2013</year>
+ <year>2001</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/efficiency_guide/xmlfiles.mk b/system/doc/efficiency_guide/xmlfiles.mk
index e3373d545a..88df9417f5 100644
--- a/system/doc/efficiency_guide/xmlfiles.mk
+++ b/system/doc/efficiency_guide/xmlfiles.mk
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2009. All Rights Reserved.
+# Copyright Ericsson AB 2009-2016. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/system/doc/embedded/Makefile b/system/doc/embedded/Makefile
index c1134dd62c..40a1b1fb23 100644
--- a/system/doc/embedded/Makefile
+++ b/system/doc/embedded/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2012. All Rights Reserved.
+# Copyright Ericsson AB 1997-2016. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/system/doc/embedded/book.xml b/system/doc/embedded/book.xml
index 5a414152d0..7737da7d2e 100644
--- a/system/doc/embedded/book.xml
+++ b/system/doc/embedded/book.xml
@@ -4,7 +4,7 @@
<book xmlns:xi="http://www.w3.org/2001/XInclude">
<header titlestyle="normal">
<copyright>
- <year>1997</year><year>2013</year>
+ <year>1997</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/embedded/embedded_nt.xml b/system/doc/embedded/embedded_nt.xml
index b35a5edf36..8e05100585 100644
--- a/system/doc/embedded/embedded_nt.xml
+++ b/system/doc/embedded/embedded_nt.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2013</year>
+ <year>1997</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -62,7 +62,7 @@
<p>For Windows NT running on standard PCs with ISA and/or PCI bus,
an extension card with a hardware watchdog can be installed.</p>
<p>For more information, see the <c>heart(3)</c> manual page in
- <c>kernel</c>.</p>
+ Kernel.</p>
</section>
</section>
@@ -72,7 +72,7 @@
to install the Erlang process as a Windows system service.
This service can start after Windows NT has booted.</p>
<p>For more information, see the <c>erlsrv</c> manual page
- in <c>erts</c>.</p>
+ in ERTS.</p>
</section>
</chapter>
diff --git a/system/doc/embedded/embedded_solaris.xml b/system/doc/embedded/embedded_solaris.xml
index ade5ad344e..eaa334fb39 100644
--- a/system/doc/embedded/embedded_solaris.xml
+++ b/system/doc/embedded/embedded_solaris.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2013</year>
+ <year>1997</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -190,7 +190,7 @@ esac</pre>
the onboard hardware watchdog can be activated,
provided a VME bus driver is added to the operating system
(see also Installation Problems).</p>
- <p>See also the <c>heart(3)</c> manual page in <c>kernel</c>.</p>
+ <p>See also the <c>heart(3)</c> manual page in Kernel.</p>
</section>
<section>
@@ -206,7 +206,7 @@ esac</pre>
<pre>
chown 0 /usr/sbin/reboot
chmod 4755 /usr/sbin/reboot</pre>
- <p>See also the <c>heart(3)</c> manual page in <c>kernel</c>.</p>
+ <p>See also the <c>heart(3)</c> manual page in Kernel.</p>
</section>
<section>
@@ -413,8 +413,8 @@ chown root mod_syslog]]></code>
<section>
<title>Related Documents</title>
<p>See the <c>os_mon(3)</c> application,
- the <c>application(3)</c> manual page in <c>kernel</c>,
- and the <c>erl(1)</c> manual page in <c>erts</c>.</p>
+ the <c>application(3)</c> manual page in Kernel,
+ and the <c>erl(1)</c> manual page in ERTS.</p>
</section>
</section>
@@ -474,7 +474,7 @@ chown root mod_syslog]]></code>
default, it must be called <c>start</c> and reside in
<c><![CDATA[<ERL_INSTALL_DIR>/bin]]></c>. Another start
program can be used, by using configuration parameter
- <c>start_prg</c> in application <c>sasl</c>.</p>
+ <c>start_prg</c> in application SASL.</p>
<p>The start program must call <c>run_erl</c> as shown below.
It must also take an optional parameter, which defaults to
<c><![CDATA[<ERL_INSTALL_DIR>/releases/start_erl.data]]></c>.</p>
@@ -484,7 +484,7 @@ chown root mod_syslog]]></code>
<p>The <c><![CDATA[<RELDIR>]]></c> directory is where new release
packets are installed, and where the release handler keeps
information about releases. For more information, see the
- <c>release_handler(3)</c> manual page in <c>sasl</c>.</p>
+ <c>release_handler(3)</c> manual page in SASL.</p>
<p>The following script illustrates the default behaviour of the
program:</p>
<code type="none"><![CDATA[
@@ -624,7 +624,7 @@ export RELDIR
exec $BINDIR/erlexec -boot $RELDIR/$VSN/start -config $RELDIR/$VSN/sys $*</code>
<p>If a diskless and/or read-only client node with the
- <c>sasl</c> configuration parameter <c>static_emulator</c> set
+ SASL configuration parameter <c>static_emulator</c> set
to <c>true</c> is about to start, the <c>-boot</c> and
<c>-config</c> flags must be changed.</p>
<p>As such a client cannot
diff --git a/system/doc/embedded/intro.xml b/system/doc/embedded/intro.xml
index 7fea2eeb82..2b9d35d24c 100644
--- a/system/doc/embedded/intro.xml
+++ b/system/doc/embedded/intro.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>1997</year>
- <year>2013</year>
+ <year>2016</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/embedded/part.xml b/system/doc/embedded/part.xml
index 7bac643be7..d359a888e7 100644
--- a/system/doc/embedded/part.xml
+++ b/system/doc/embedded/part.xml
@@ -4,7 +4,7 @@
<part xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>1997</year><year>2013</year>
+ <year>1997</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/embedded/starting.xml b/system/doc/embedded/starting.xml
index f9454f1021..11bf9b412a 100644
--- a/system/doc/embedded/starting.xml
+++ b/system/doc/embedded/starting.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1996</year><year>2013</year>
+ <year>1996</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -69,7 +69,7 @@
default, it must be called <c>start</c> and reside in
<c><![CDATA[<ERL_INSTALL_DIR>/bin]]></c>. Another start program can be
used, by using the configuration parameter <c>start_prg</c> in
- the application <c>sasl</c>.</p>
+ application SASL.</p>
<p>The start program must call <c>run_erl</c> as shown below.
It must also take an optional parameter which defaults to
<c><![CDATA[<ERL_INSTALL_DIR>/bin/start_erl.data]]></c>.
@@ -80,8 +80,8 @@
</p>
<p>The <c><![CDATA[<RELDIR>]]></c> directory is where new release packets
are installed, and where the release handler keeps information
- about releases. See <c>release_handler(3)</c> in the
- application <c>sasl</c> for further information.
+ about releases. See <c>release_handler(3)</c> in
+ application SASL for further information.
</p>
<p>The following script illustrates the default behaviour of the
program.
@@ -228,7 +228,7 @@ export PROGNAME
export RELDIR
exec $BINDIR/erlexec -boot $RELDIR/$VSN/start -config $RELDIR/$VSN/sys $* </code>
- <p>If a diskless and/or read-only client node with the <c>sasl</c>
+ <p>If a diskless and/or read-only client node with the SASL
configuration parameter <c>static_emulator</c> set to <c>true</c>
is about to start the <c>-boot</c> and <c>-config</c> flags must be
changed. As such a client can not read a new <c>start_erl.data</c>
diff --git a/system/doc/embedded/target.xml b/system/doc/embedded/target.xml
index 20ef6b0fc6..754269aa2f 100644
--- a/system/doc/embedded/target.xml
+++ b/system/doc/embedded/target.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1996</year><year>2013</year>
+ <year>1996</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/embedded/vme_problems.xml b/system/doc/embedded/vme_problems.xml
index 54618935cd..ac276ce9d3 100644
--- a/system/doc/embedded/vme_problems.xml
+++ b/system/doc/embedded/vme_problems.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>1997</year>
- <year>2013</year>
+ <year>2016</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/embedded/xmlfiles.mk b/system/doc/embedded/xmlfiles.mk
index 4446aa1516..1e0c71c726 100644
--- a/system/doc/embedded/xmlfiles.mk
+++ b/system/doc/embedded/xmlfiles.mk
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2009-2013. All Rights Reserved.
+# Copyright Ericsson AB 2009-2016. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/system/doc/embedded/xntp.xml b/system/doc/embedded/xntp.xml
index 2f4dc9a534..46213c7865 100644
--- a/system/doc/embedded/xntp.xml
+++ b/system/doc/embedded/xntp.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>1997</year>
- <year>2013</year>
+ <year>2016</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/getting_started/Makefile b/system/doc/getting_started/Makefile
index f16dc0dde1..1fe3d39e4e 100644
--- a/system/doc/getting_started/Makefile
+++ b/system/doc/getting_started/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1996-2012. All Rights Reserved.
+# Copyright Ericsson AB 1996-2016. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/system/doc/getting_started/book.xml b/system/doc/getting_started/book.xml
index 8dfca19480..1d92105429 100644
--- a/system/doc/getting_started/book.xml
+++ b/system/doc/getting_started/book.xml
@@ -4,7 +4,7 @@
<book xmlns:xi="http://www.w3.org/2001/XInclude">
<header titlestyle="normal">
<copyright>
- <year>1996</year><year>2013</year>
+ <year>1996</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/getting_started/conc_prog.xml b/system/doc/getting_started/conc_prog.xml
index 9f13ee4802..f3136898ad 100644
--- a/system/doc/getting_started/conc_prog.xml
+++ b/system/doc/getting_started/conc_prog.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2013</year>
+ <year>2003</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/getting_started/intro.xml b/system/doc/getting_started/intro.xml
index 6ac4f912fe..afae4e8c18 100644
--- a/system/doc/getting_started/intro.xml
+++ b/system/doc/getting_started/intro.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2013</year>
+ <year>2003</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/getting_started/part.xml b/system/doc/getting_started/part.xml
index 4b902f4c63..71e551a404 100644
--- a/system/doc/getting_started/part.xml
+++ b/system/doc/getting_started/part.xml
@@ -4,7 +4,7 @@
<part xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>1997</year><year>2013</year>
+ <year>1997</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/getting_started/records_macros.xml b/system/doc/getting_started/records_macros.xml
index dd2441b64e..3fcdb10088 100644
--- a/system/doc/getting_started/records_macros.xml
+++ b/system/doc/getting_started/records_macros.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2013</year>
+ <year>2003</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/getting_started/robustness.xml b/system/doc/getting_started/robustness.xml
index abd5892b80..6932f0ca0f 100644
--- a/system/doc/getting_started/robustness.xml
+++ b/system/doc/getting_started/robustness.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2013</year>
+ <year>2003</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/getting_started/seq_prog.xml b/system/doc/getting_started/seq_prog.xml
index 5698405ed2..6b7e1cd24f 100644
--- a/system/doc/getting_started/seq_prog.xml
+++ b/system/doc/getting_started/seq_prog.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2013</year>
+ <year>2003</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/getting_started/xmlfiles.mk b/system/doc/getting_started/xmlfiles.mk
index 892db0e8de..d5a41121d6 100644
--- a/system/doc/getting_started/xmlfiles.mk
+++ b/system/doc/getting_started/xmlfiles.mk
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2009. All Rights Reserved.
+# Copyright Ericsson AB 2009-2016. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/system/doc/installation_guide/Makefile b/system/doc/installation_guide/Makefile
index 52485382d5..673c203422 100644
--- a/system/doc/installation_guide/Makefile
+++ b/system/doc/installation_guide/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1996-2014. All Rights Reserved.
+# Copyright Ericsson AB 1996-2016. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/system/doc/installation_guide/book.xml b/system/doc/installation_guide/book.xml
index 92a64345c0..a7686252c6 100644
--- a/system/doc/installation_guide/book.xml
+++ b/system/doc/installation_guide/book.xml
@@ -4,7 +4,7 @@
<book xmlns:xi="http://www.w3.org/2001/XInclude">
<header titlestyle="normal">
<copyright>
- <year>1997</year><year>2013</year>
+ <year>1997</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/installation_guide/install-binary.xml b/system/doc/installation_guide/install-binary.xml
index 43f5a57077..b070c02633 100644
--- a/system/doc/installation_guide/install-binary.xml
+++ b/system/doc/installation_guide/install-binary.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2000</year><year>2014</year>
+ <year>2000</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/installation_guide/part.xml b/system/doc/installation_guide/part.xml
index 0aacd0f49b..7e51e6ae84 100644
--- a/system/doc/installation_guide/part.xml
+++ b/system/doc/installation_guide/part.xml
@@ -4,7 +4,7 @@
<part xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>2000</year><year>2014</year>
+ <year>2000</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/installation_guide/xmlfiles.mk b/system/doc/installation_guide/xmlfiles.mk
index 05effe1534..3f720e1ee5 100644
--- a/system/doc/installation_guide/xmlfiles.mk
+++ b/system/doc/installation_guide/xmlfiles.mk
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2009-2014. All Rights Reserved.
+# Copyright Ericsson AB 2009-2016. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/system/doc/oam/Makefile b/system/doc/oam/Makefile
index 0638a4dbd6..9095744423 100644
--- a/system/doc/oam/Makefile
+++ b/system/doc/oam/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2012. All Rights Reserved.
+# Copyright Ericsson AB 1997-2016. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/system/doc/oam/book.xml b/system/doc/oam/book.xml
index 93f5fe344a..05aa2334a5 100644
--- a/system/doc/oam/book.xml
+++ b/system/doc/oam/book.xml
@@ -4,7 +4,7 @@
<book xmlns:xi="http://www.w3.org/2001/XInclude">
<header titlestyle="normal">
<copyright>
- <year>1997</year><year>2013</year>
+ <year>1997</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/oam/oam_intro.xml b/system/doc/oam/oam_intro.xml
index 22a2080fd9..8b8d69e638 100644
--- a/system/doc/oam/oam_intro.xml
+++ b/system/doc/oam/oam_intro.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2013</year>
+ <year>1997</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -178,7 +178,7 @@
<section>
<title>MIB Structure</title>
<p>The top-level OTP MIB is called <c>OTP-REG</c> and it is
- included in the <c>sasl</c> application. All other OTP MIBs
+ included in the SASL application. All other OTP MIBs
import some objects from this MIB.</p>
<p>Each MIB is contained in one application. The MIB text
@@ -188,7 +188,7 @@
<c><![CDATA[include/<MIB>.hrl]]></c>, and the compiled MIBs
are stored under <c><![CDATA[priv/mibs/<MIB>.bin]]></c>.
For example, the <c>OTP-MIB</c> is included in the
- <c>sasl</c> application:</p>
+ SASL application:</p>
<code type="none">
sasl-1.3/mibs/OTP-MIB.mib
@@ -211,11 +211,11 @@ snmp:c("MY-MIB", [{il, ["sasl/priv/mibs"]}]).</code>
<p>The following MIBs are defined in the OTP system:</p>
<list type="bulleted">
- <item><p><c>OTP-REG)</c> (in <c>sasl</c>) contains the top-level
+ <item><p><c>OTP-REG)</c> (in SASL) contains the top-level
OTP registration objects, used by all other MIBs.</p></item>
- <item><p><c>OTP-TC</c> (in <c>sasl</c>) contains the general
+ <item><p><c>OTP-TC</c> (in SASL) contains the general
Textual Conventions, which can be used by any other MIB.</p></item>
- <item><p><c>OTP-MIB</c> (in <c>sasl</c>) contains objects for
+ <item><p><c>OTP-MIB</c> (in SASL) contains objects for
instrumentation of the Erlang nodes, the Erlang machines,
and the applications in the system.</p></item>
<item><p><c>OTP-OS-MON-MIB</c> (in <c>oc_mon</c>) contains
diff --git a/system/doc/oam/part.xml b/system/doc/oam/part.xml
index efbaa05b94..817b70751c 100644
--- a/system/doc/oam/part.xml
+++ b/system/doc/oam/part.xml
@@ -4,7 +4,7 @@
<part xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>1997</year><year>2013</year>
+ <year>1997</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/oam/xmlfiles.mk b/system/doc/oam/xmlfiles.mk
index 5876243466..b2351c661c 100644
--- a/system/doc/oam/xmlfiles.mk
+++ b/system/doc/oam/xmlfiles.mk
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2009. All Rights Reserved.
+# Copyright Ericsson AB 2009-2016. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/system/doc/programming_examples/Makefile b/system/doc/programming_examples/Makefile
index e5f7a330f4..237076d770 100644
--- a/system/doc/programming_examples/Makefile
+++ b/system/doc/programming_examples/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2003-2012. All Rights Reserved.
+# Copyright Ericsson AB 2003-2016. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/system/doc/programming_examples/book.xml b/system/doc/programming_examples/book.xml
index c6eb4fec97..0f0fca5874 100644
--- a/system/doc/programming_examples/book.xml
+++ b/system/doc/programming_examples/book.xml
@@ -4,7 +4,7 @@
<book xmlns:xi="http://www.w3.org/2001/XInclude">
<header titlestyle="normal">
<copyright>
- <year>2003</year><year>2013</year>
+ <year>2003</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/programming_examples/funs.xmlsrc b/system/doc/programming_examples/funs.xmlsrc
index 8469f0871c..bb519be612 100644
--- a/system/doc/programming_examples/funs.xmlsrc
+++ b/system/doc/programming_examples/funs.xmlsrc
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2013</year>
+ <year>2003</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -212,7 +212,7 @@ f(...) ->
...
end, ...)
...</code>
- <p>instead of writng the following code:</p>
+ <p>instead of writing the following code:</p>
<code type="none">
f(...) ->
Y = ...
diff --git a/system/doc/programming_examples/list_comprehensions.xml b/system/doc/programming_examples/list_comprehensions.xml
index 5667571ec5..706cb337ad 100644
--- a/system/doc/programming_examples/list_comprehensions.xml
+++ b/system/doc/programming_examples/list_comprehensions.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2013</year>
+ <year>2003</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/programming_examples/part.xml b/system/doc/programming_examples/part.xml
index e1f8cc5d57..930646ff4b 100644
--- a/system/doc/programming_examples/part.xml
+++ b/system/doc/programming_examples/part.xml
@@ -4,7 +4,7 @@
<part xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>2003</year><year>2013</year>
+ <year>2003</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/programming_examples/records.xml b/system/doc/programming_examples/records.xml
index 6bda6dc0fd..074aa636b4 100644
--- a/system/doc/programming_examples/records.xml
+++ b/system/doc/programming_examples/records.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2013</year>
+ <year>2003</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -93,7 +93,7 @@ person</pre>
at compile time, not at runtime. For details on records
in the shell, see the
<seealso marker="stdlib:shell">shell(3)</seealso>
- manual page in <c>stdlib</c>.</p>
+ manual page in STDLIB.</p>
</section>
<section>
diff --git a/system/doc/programming_examples/xmlfiles.mk b/system/doc/programming_examples/xmlfiles.mk
index cc77f48253..5129e488f4 100644
--- a/system/doc/programming_examples/xmlfiles.mk
+++ b/system/doc/programming_examples/xmlfiles.mk
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2009. All Rights Reserved.
+# Copyright Ericsson AB 2009-2016. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/system/doc/reference_manual/Makefile b/system/doc/reference_manual/Makefile
index 30febb1ade..e14a056979 100644
--- a/system/doc/reference_manual/Makefile
+++ b/system/doc/reference_manual/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2003-2012. All Rights Reserved.
+# Copyright Ericsson AB 2003-2016. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/system/doc/reference_manual/book.xml b/system/doc/reference_manual/book.xml
index 6b7306fb77..590d3580a4 100644
--- a/system/doc/reference_manual/book.xml
+++ b/system/doc/reference_manual/book.xml
@@ -4,7 +4,7 @@
<book xmlns:xi="http://www.w3.org/2001/XInclude">
<header titlestyle="normal">
<copyright>
- <year>2003</year><year>2013</year>
+ <year>2003</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/reference_manual/code_loading.xml b/system/doc/reference_manual/code_loading.xml
index e9da40e02f..f6fd2911fa 100644
--- a/system/doc/reference_manual/code_loading.xml
+++ b/system/doc/reference_manual/code_loading.xml
@@ -130,26 +130,6 @@ loop() ->
<marker id="on_load"></marker>
<title>Running a Function When a Module is Loaded</title>
- <warning>
- <p>The <c>on_load</c> feature is to be considered experimental
- as there are a number of known weak points in current semantics,
- which therefore might change in future Erlang/OTP releases:</p>
- <list>
- <item><p>Doing external call in <c>on_load</c> to the module itself
- leads to deadlock.</p></item>
- <item><p>At module upgrade, other processes calling the module
- get suspended waiting for <c>on_load</c> to finish. This can be very bad
- for applications with demands on realtime characteristics.</p></item>
- <item><p>At module upgrade, no rollback is done if the
- <c>on_load</c> function fails.
- The system is left in a bad limbo state without any working
- and reachable instance of the module.</p></item>
- </list>
- <p>The problems with module upgrade described above can be fixed in future
- Erlang/OTP releases by changing the behaviour to not make the module reachable until
- after the <c>on_load</c> function has successfully returned.</p>
- </warning>
-
<p>The <c>-on_load()</c> directive names a function that is to
be run automatically when a module is loaded.</p>
<p>Its syntax is as follows:</p>
@@ -159,20 +139,35 @@ loop() ->
<p>It is not necessary to export the function. It is called in a
freshly spawned process (which terminates as soon as the function
- returns). The function must return <c>ok</c> if the module is to
- remain loaded and become callable, or any other value if the module
- is to be unloaded. Generating an exception also causes the
- module to be unloaded. If the return value is not an atom,
- a warning error report is sent to the error logger.</p>
-
- <p>A process that calls any function in a module whose <c>on_load</c>
- function has not yet returned, is suspended until the <c>on_load</c>
- function has returned.</p>
+ returns).</p>
+
+ <p>The function must return <c>ok</c> if the module is to
+ become the new current code for the module and become
+ callable.</p>
+
+ <p>Returning any other value or generating an exception
+ causes the new code to be unloaded. If the return value is not an
+ atom, a warning error report is sent to the error logger.</p>
+
+ <p>If there already is current code for the module, that code will
+ remain current and can be called until the <c>on_load</c> function
+ has returned. If the <c>on_load</c> function fails, the current
+ code (if any) will remain current. If there is no current code for
+ a module, any process that makes an external call to the module
+ before the <c>on_load</c> function has finished will be suspended
+ until the <c>on_load</c> function have finished.</p>
+
+ <note>
+ <p>Before OTP 19, if the <c>on_load</c> function failed, any
+ previously current code would become old, essentially leaving
+ the system without any working and reachable instance of the
+ module. That problem has been eliminated in OTP 19.</p>
+ </note>
<p>In embedded mode, first all modules are loaded.
Then all <c>on_load</c> functions are called. The system is
terminated unless all of the <c>on_load</c> functions return
- <c>ok</c></p>.
+ <c>ok</c>.</p>
<p><em>Example:</em></p>
diff --git a/system/doc/reference_manual/expressions.xml b/system/doc/reference_manual/expressions.xml
index 668a51d6bc..1a3d19aed1 100644
--- a/system/doc/reference_manual/expressions.xml
+++ b/system/doc/reference_manual/expressions.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2015</year>
+ <year>2003</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -245,13 +245,13 @@ lists:keysearch(Name, 1, List)</code>
handle(Msg, State)
spawn(m, init, [])</code>
<p><em>Examples</em> where <c>ExprF</c> is a fun:</p>
- <code type="none">
-Fun1 = fun(X) -> X+1 end
-Fun1(3)
-=> 4
-
-fun lists:append/2([1,2], [3,4])
-=> [1,2,3,4]</code>
+ <pre>
+1> <input>Fun1 = fun(X) -> X+1 end,</input>
+<input>Fun1(3).</input>
+4
+2> <input>fun lists:append/2([1,2], [3,4]).</input>
+[1,2,3,4]
+3> </pre>
<p>Notice that when calling a local function, there is a difference
between using the implicitly or fully qualified function name.
@@ -568,10 +568,14 @@ Expr1 <input>op</input> Expr2</pre>
<p>The arguments can be of different data types. The following
order is defined:</p>
<pre>
-number &lt; atom &lt; reference &lt; fun &lt; port &lt; pid &lt; tuple &lt; list &lt; bit string</pre>
+number &lt; atom &lt; reference &lt; fun &lt; port &lt; pid &lt; tuple &lt; map &lt; nil &lt; list &lt; bit string</pre>
<p>Lists are compared element by element. Tuples are ordered by
size, two tuples with the same size are compared element by
element.</p>
+ <p>Maps are ordered by size, two maps with the same size are compared by keys in
+ ascending term order and then by values in key order.
+ In maps key order integers types are considered less than floats types.
+ </p>
<p>When comparing an integer to a float, the term with the lesser
precision is converted into the type of the other term, unless the
operator is one of <c>=:=</c> or <c>=/=</c>. A float is more precise than
@@ -591,7 +595,11 @@ true
2> <input>1=:=1.0.</input>
false
3> <input>1 > a.</input>
-false</pre>
+false
+4> <input>#{c => 3} > #{a => 1, b => 2}.</input>
+false
+4> <input>#{a => 1, b => 2} == #{a => 1.0, b => 2.0}.</input>
+true</pre>
</section>
<section>
@@ -996,7 +1004,7 @@ M4 = M3#{a := 2, b := 3}. % 'a' and 'b' was added in `M1` and `M2`.</code>
</p>
<list>
<item><p>A <c>badmatch</c> exception.</p>
- <p>This is if it is used in the context of the matching operator
+ <p>This is if it is used in the context of the match operator
as in the example.</p>
</item>
<item><p>Or resulting in the next clause being tested in function heads and
@@ -1077,7 +1085,7 @@ Ei = Value |
<p>Used in a bit string construction, <c>Value</c> is an expression
that is to evaluate to an integer, float, or bit string. If the
expression is not a single literal or variable, it
- is to be enclosed in parenthesis.</p>
+ is to be enclosed in parentheses.</p>
<p>Used in a bit string matching, <c>Value</c> must be a variable,
or an integer, float, or string.</p>
@@ -1311,7 +1319,7 @@ catch Expr</code>
{'EXIT',{badarith,[...]}}</pre>
<p>Notice that <c>catch</c> has low precedence and catch
subexpressions often needs to be enclosed in a block
- expression or in parenthesis:</p>
+ expression or in parentheses:</p>
<pre>
3> <input>A = catch 1+2.</input>
** 1: syntax error before: 'catch' **
@@ -1533,7 +1541,16 @@ end</pre>
<pre>
1> <input>[X*2 || X &lt;- [1,2,3]].</input>
[2,4,6]</pre>
- <p>More examples are provoded in
+ <p>When there are no generators or bit string generators, a list comprehension
+ returns either a list with one element (the result of evaluating <c>Expr</c>)
+ if all filters are true or an empty list otherwise.</p>
+ <p><em>Example:</em></p>
+ <pre>
+1> <input>[2 || is_integer(2)].</input>
+[2]
+2> <input>[x || is_integer(x)].</input>
+[]</pre>
+ <p>More examples are provided in
<seealso marker="doc/programming_examples:list_comprehensions">
Programming Examples.</seealso></p>
@@ -1548,9 +1565,11 @@ end</pre>
<p>Bit string comprehensions are written with
the following syntax:</p>
<pre>
-&lt;&lt; BitString || Qualifier1,...,QualifierN &gt;&gt;</pre>
- <p>Here, <c>BitString</c> is a bit string expression and each
- <c>Qualifier</c> is either a generator, a bit string generator or a filter.</p>
+&lt;&lt; BitStringExpr || Qualifier1,...,QualifierN &gt;&gt;</pre>
+ <p><c>BitStringExpr</c> is an expression that evalutes to a bit
+ string. If <c>BitStringExpr</c> is a function call, it must be
+ enclosed in parentheses. Each <c>Qualifier</c> is either a
+ generator, a bit string generator or a filter.</p>
<list type="bulleted">
<item>A <em>generator</em> is written as: <br></br>
&nbsp;&nbsp;<c><![CDATA[Pattern <- ListExpr]]></c>. <br></br>
diff --git a/system/doc/reference_manual/macros.xml b/system/doc/reference_manual/macros.xml
index 3b1f72e5d6..350bb1d123 100644
--- a/system/doc/reference_manual/macros.xml
+++ b/system/doc/reference_manual/macros.xml
@@ -146,6 +146,10 @@ bar(X) ->
<item>The current line number.</item>
<tag><c>?MACHINE</c>.</tag>
<item>The machine name, <c>'BEAM'</c>.</item>
+ <tag><c>?FUNCTION_NAME</c></tag>
+ <item>The name of the current function.</item>
+ <tag><c>?FUNCTION_ARITY</c></tag>
+ <item>The arity (number of arguments) for the current function.</item>
</taglist>
</section>
@@ -230,6 +234,53 @@ or
</section>
<section>
+ <title>-error() and -warning() directives</title>
+
+ <p>The directive <c>-error(Term)</c> causes a compilation error.</p>
+
+ <p><em>Example:</em></p>
+ <code type="none">
+-module(t).
+-export([version/0]).
+
+-ifdef(VERSION).
+version() -> ?VERSION.
+-else.
+-error("Macro VERSION must be defined.").
+version() -> "".
+-endif.</code>
+
+ <p>The error message will look like this:</p>
+
+ <pre>
+% <input>erlc t.erl</input>
+t.erl:7: -error("Macro VERSION must be defined.").</pre>
+
+ <p>The directive <c>-warning(Term)</c> causes a compilation warning.</p>
+
+ <p><em>Example:</em></p>
+ <code type="none">
+-module(t).
+-export([version/0]).
+
+-ifndef(VERSION).
+-warning("Macro VERSION not defined -- using default version.").
+-define(VERSION, "0").
+-endif.
+version() -> ?VERSION.</code>
+
+ <p>The warning message will look like this:</p>
+
+ <pre>
+% <input>erlc t.erl</input>
+t.erl:5: Warning: -warning("Macro VERSION not defined -- using default version.").</pre>
+
+ <p>The <c>-error()</c> and <c>-warning()</c> directives were added
+ in OTP 19.</p>
+
+ </section>
+
+ <section>
<title>Stringifying Macro Arguments</title>
<p>The construction <c>??Arg</c>, where <c>Arg</c> is a macro
argument, is expanded to a string containing the tokens of
@@ -249,5 +300,6 @@ io:format("Call ~s: ~w~n",["you : function ( 2 , 1 )",you:function(2,1)]).</code
<p>That is, a trace output, with both the function called and
the resulting value.</p>
</section>
+
</chapter>
diff --git a/system/doc/reference_manual/modules.xml b/system/doc/reference_manual/modules.xml
index 5f2ac2a67d..96968b547e 100644
--- a/system/doc/reference_manual/modules.xml
+++ b/system/doc/reference_manual/modules.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2015</year>
+ <year>2003</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -144,6 +144,7 @@ fact(0) -> % |
<list type="bulleted">
<item><c>gen_server</c></item>
<item><c>gen_fsm</c></item>
+ <item><c>gen_statem</c></item>
<item><c>gen_event</c></item>
<item><c>supervisor</c></item>
</list>
diff --git a/system/doc/reference_manual/part.xml b/system/doc/reference_manual/part.xml
index 58483b099a..3d31157973 100644
--- a/system/doc/reference_manual/part.xml
+++ b/system/doc/reference_manual/part.xml
@@ -4,7 +4,7 @@
<part xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>2003</year><year>2014</year>
+ <year>2003</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/reference_manual/patterns.xml b/system/doc/reference_manual/patterns.xml
index 043d282de7..57b84b4dfc 100644
--- a/system/doc/reference_manual/patterns.xml
+++ b/system/doc/reference_manual/patterns.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2013</year>
+ <year>2003</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/reference_manual/processes.xml b/system/doc/reference_manual/processes.xml
index 6755bd8be6..f656d0318e 100644
--- a/system/doc/reference_manual/processes.xml
+++ b/system/doc/reference_manual/processes.xml
@@ -100,11 +100,9 @@ spawn(Module, Name, Args) -> pid()
<item><c>exit(Reason)</c></item>
<item><c>erlang:error(Reason)</c></item>
<item><c>erlang:error(Reason, Args)</c></item>
- <item><c>erlang:fault(Reason)</c></item>
- <item><c>erlang:fault(Reason, Args)</c></item>
</list>
<p>The process then terminates with reason <c>Reason</c> for
- <c>exit/1</c> or <c>{Reason,Stack} for the others</c>.</p>
+ <c>exit/1</c> or <c>{Reason,Stack}</c> for the others.</p>
<p>A process can also be terminated if it receives an exit signal
with another exit reason than <c>normal</c>, see
<seealso marker="#errors">Error Handling</seealso>.</p>
diff --git a/system/doc/reference_manual/typespec.xml b/system/doc/reference_manual/typespec.xml
index 7891f3a6b9..ced584ed35 100644
--- a/system/doc/reference_manual/typespec.xml
+++ b/system/doc/reference_manual/typespec.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2015</year>
+ <year>2003</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -47,7 +47,7 @@
<list type="bulleted">
<item>To document function interfaces</item>
<item>To provide more information for bug detection tools,
- such as <c>Dialyzer</c></item>
+ such as Dialyzer</item>
<item>To be exploited by documentation tools, such as EDoc, for
generating program documentation of various forms</item>
</list>
@@ -69,7 +69,7 @@
<p>
For integers and atoms, it is allowed for singleton types; for example,
the integers
- <c>-1</c> and <c>42</c>, or the atoms <c>'foo'</c> and <c>'bar'</c>).
+ <c>-1</c> and <c>42</c>, or the atoms <c>'foo'</c> and <c>'bar'</c>.
All other types are built using unions of either predefined
types or singleton types. In a type union between a type and one
@@ -132,15 +132,18 @@
| nonempty_list(Type) %% Proper non-empty list
Map :: map() %% stands for a map of any size
- | #{} %% stands for a map of any size
+ | #{} %% stands for the empty map
| #{PairList}
Tuple :: tuple() %% stands for a tuple of any size
| {}
| {TList}
- PairList :: Type => Type
- | Type => Type, PairList
+ PairList :: Pair
+ | Pair, PairList
+
+ Pair :: Type := Type %% denotes a pair that must be present
+ | Type => Type
TList :: Type
| Type, TList
@@ -148,9 +151,9 @@
Union :: Type1 | Type2
]]></pre>
<p>
- The general form of bitstrings is <c>&lt;&lt;_:M, _:_*N&gt;&gt;</c>,
+ The general form of bit strings is <c>&lt;&lt;_:M, _:_*N&gt;&gt;</c>,
where <c>M</c> and <c>N</c> are positive integers. It denotes a
- bitstring that is <c>M + (k*N)</c> bits long (that is, a bitstring that
+ bit string that is <c>M + (k*N)</c> bits long (that is, a bit string that
starts with <c>M</c> bits and continues with <c>k</c> segments of
<c>N</c> bits each, where <c>k</c> is also a positive integer).
The notations <c>&lt;&lt;_:_*N&gt;&gt;</c>, <c>&lt;&lt;_:M&gt;&gt;</c>,
@@ -170,6 +173,17 @@
The notation <c>[]</c> specifies the singleton type for the empty list.
</p>
<p>
+ The general form of maps is <c>#{PairList}</c>. The key types in
+ <c>PairList</c> are allowed to overlap, and if they do, the
+ leftmost pair takes precedence. A map pair has a key in
+ <c>PairList</c> if it belongs to this type.
+ </p>
+ <p>
+ Notice that the syntactic representation of <c>map()</c> is
+ <c>#{any() =&gt; any()}</c> (or <c>#{_ =&gt; _}</c>), not <c>#{}</c>.
+ The notation <c>#{}</c> specifies the singleton type for the empty map.
+ </p>
+ <p>
For convenience, the following types are also built-in.
They can be thought as predefined aliases for the type unions also shown in
the table.
@@ -197,6 +211,9 @@
<cell><c>char()</c></cell><cell><c>0..16#10ffff</c></cell>
</row>
<row>
+ <cell><c>nil()</c></cell><cell><c>[]</c></cell>
+ </row>
+ <row>
<cell><c>number()</c></cell><cell><c>integer() | float()</c></cell>
</row>
<row>
@@ -299,12 +316,6 @@
This is described in <seealso marker="#typeinrecords">
Type Information in Record Declarations</seealso>.
</p>
- <note>
- <p>Map types, both <c>map()</c> and <c>#{...}</c>,
- are considered experimental during OTP 17.</p>
- <p>No type information of maps pairs, only the containing map types,
- are used by Dialyzer in OTP 17.</p>
- </note>
</section>
<section>
@@ -312,7 +323,7 @@
<p>
As seen, the basic syntax of a type is an atom followed by closed
parentheses. New types are declared using <c>-type</c> and <c>-opaque</c>
- compiler attributes as in the following:
+ attributes as in the following:
</p>
<pre>
-type my_struct_type() :: Type.
@@ -398,11 +409,13 @@
The initial values for fields are to be compatible
with (that is, a member of) the corresponding types.
This is checked by the compiler and results in a compilation error
- if a violation is detected. For fields without initial values,
- the singleton type <c>'undefined'</c> is added to all declared types.
- In other words, the following two record declarations have identical
- effects:
+ if a violation is detected.
</p>
+ <note>
+ <p>Before Erlang/OTP 19, for fields without initial values,
+ the singleton type <c>'undefined'</c> was added to all declared types.
+ In other words, the following two record declarations had identical
+ effects:</p>
<pre>
-record(rec, {f1 = 42 :: integer(),
f2 :: float(),
@@ -412,9 +425,10 @@
f2 :: 'undefined' | float(),
f3 :: 'undefined' | 'a' | 'b'}).</pre>
<p>
- For this reason, it is recommended that records contain initializers,
- whenever possible.
+ This is no longer the case. If you require <c>'undefined'</c> in your record field
+ type, you must explicitly add it to the typespec, as in the 2nd example.
</p>
+ </note>
<p>
Any record, containing type information or not, once defined,
can be used as a type using the following syntax:
@@ -435,8 +449,8 @@
<section>
<title>Specifications for Functions</title>
<p>
- A specification (or contract) for a function is given using the new
- compiler attribute <c>-spec</c>. The general format is as follows:
+ A specification (or contract) for a function is given using the
+ <c>-spec</c> attribute. The general format is as follows:
</p>
<pre>
-spec Module:Function(ArgType1, ..., ArgTypeN) -> ReturnType.</pre>
@@ -451,7 +465,7 @@
explicitly) import these functions.
</p>
<p>
- Within a given module, the following shorthand suffice in most cases:
+ Within a given module, the following shorthand suffices in most cases:
</p>
<pre>
-spec Function(ArgType1, ..., ArgTypeN) -> ReturnType.</pre>
@@ -492,7 +506,8 @@
</p>
<pre> -spec id(X) -> X when X :: tuple().</pre>
<p>
- Currently, the <c>::</c> constraint (read as <c>is_subtype</c>) is
+ Currently, the <c>::</c> constraint
+ (read as &laquo;is a subtype of&raquo;) is
the only guard constraint that can be used in the <c>'when'</c>
part of a <c>'-spec'</c> attribute.
</p>
@@ -510,7 +525,7 @@
<em>the same</em> tuple.
</p>
<p>
- However, it is up to the tools that process the specificationss
+ However, it is up to the tools that process the specifications
to choose whether to take this extra information into account
or not.
</p>
@@ -526,16 +541,6 @@
<pre>
-spec foo({X, integer()}) -> X when X :: atom()
; ([Y]) -> Y when Y :: number().</pre>
- <note>
- <p>
- For backwards compatibility the following form is also allowed:
- </p>
- <pre> -spec id(X) -> X when is_subtype(X, tuple()).</pre>
- <p>
- but its use is discouraged. It will be removed in a future
- Erlang/OTP release.
- </p>
- </note>
<p>
Some functions in Erlang are not meant to return;
either because they define servers or because they are used to
diff --git a/system/doc/reference_manual/xmlfiles.mk b/system/doc/reference_manual/xmlfiles.mk
index 323b94c0de..61637ae701 100644
--- a/system/doc/reference_manual/xmlfiles.mk
+++ b/system/doc/reference_manual/xmlfiles.mk
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2009. All Rights Reserved.
+# Copyright Ericsson AB 2009-2016. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/system/doc/system_architecture_intro/Makefile b/system/doc/system_architecture_intro/Makefile
index 8bc86ab312..446e66205c 100644
--- a/system/doc/system_architecture_intro/Makefile
+++ b/system/doc/system_architecture_intro/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2012. All Rights Reserved.
+# Copyright Ericsson AB 1997-2016. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/system/doc/system_architecture_intro/book.xml b/system/doc/system_architecture_intro/book.xml
index 318f940a18..4b9f03c7f9 100644
--- a/system/doc/system_architecture_intro/book.xml
+++ b/system/doc/system_architecture_intro/book.xml
@@ -4,7 +4,7 @@
<book xmlns:xi="http://www.w3.org/2001/XInclude">
<header titlestyle="normal">
<copyright>
- <year>1997</year><year>2013</year>
+ <year>1997</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/system_architecture_intro/part.xml b/system/doc/system_architecture_intro/part.xml
index eb0f9e0ba6..c000892449 100644
--- a/system/doc/system_architecture_intro/part.xml
+++ b/system/doc/system_architecture_intro/part.xml
@@ -4,7 +4,7 @@
<part xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>1997</year><year>2013</year>
+ <year>1997</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/system_architecture_intro/sys_arch_intro.xml b/system/doc/system_architecture_intro/sys_arch_intro.xml
index b9535f66f8..cf75e1f100 100644
--- a/system/doc/system_architecture_intro/sys_arch_intro.xml
+++ b/system/doc/system_architecture_intro/sys_arch_intro.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2000</year><year>2013</year>
+ <year>2000</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/system_architecture_intro/xmlfiles.mk b/system/doc/system_architecture_intro/xmlfiles.mk
index 6e7e712703..60c2047796 100644
--- a/system/doc/system_architecture_intro/xmlfiles.mk
+++ b/system/doc/system_architecture_intro/xmlfiles.mk
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2009. All Rights Reserved.
+# Copyright Ericsson AB 2009-2016. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/system/doc/system_principles/Makefile b/system/doc/system_principles/Makefile
index 2bb84474df..77edea8f58 100644
--- a/system/doc/system_principles/Makefile
+++ b/system/doc/system_principles/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1996-2012. All Rights Reserved.
+# Copyright Ericsson AB 1996-2016. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/system/doc/system_principles/book.xml b/system/doc/system_principles/book.xml
index 11eacba578..cd84d4cf6b 100644
--- a/system/doc/system_principles/book.xml
+++ b/system/doc/system_principles/book.xml
@@ -4,7 +4,7 @@
<book xmlns:xi="http://www.w3.org/2001/XInclude">
<header titlestyle="normal">
<copyright>
- <year>1996</year><year>2013</year>
+ <year>1996</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/system_principles/create_target.xmlsrc b/system/doc/system_principles/create_target.xmlsrc
index ccc26081c3..f9b27ffc35 100644
--- a/system/doc/system_principles/create_target.xmlsrc
+++ b/system/doc/system_principles/create_target.xmlsrc
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2002</year><year>2014</year>
+ <year>2002</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -374,10 +374,10 @@ os> <input>/usr/local/erl-target/bin/to_erl /tmp/erlang.pipe.1</input></pre>
</p>
<pre>
2> <input>release_handler:install_release(Vsn).</input>
-<output>{continue_after_restart,"FIRST",[]}
+{continue_after_restart,"FIRST",[]}
heart: Tue Apr 1 12:15:10 2014: Erlang has closed.
heart: Tue Apr 1 12:15:11 2014: Executed "/usr/local/erl-target/bin/start /usr/local/erl-target/releases/new_start_erl.data" -> 0. Terminating.
-[End]</output></pre>
+[End]</pre>
<p>
The above return value and output after the call to
<c>release_handler:install_release/1</c> means that the
@@ -398,12 +398,12 @@ os> <input>/usr/local/erl-target/bin/to_erl /tmp/erlang.pipe.2</input></pre>
</p>
<pre>
1> <input>release_handler:which_releases().</input>
-<output>[{"MYSYSTEM","SECOND",
+[{"MYSYSTEM","SECOND",
["kernel-3.0","stdlib-2.0","sasl-2.4","pea-2.0"],
current},
{"MYSYSTEM","FIRST",
["kernel-2.16.4","stdlib-1.19.4","sasl-2.3.4","pea-1.0"],
- permanent}]</output></pre>
+ permanent}]</pre>
<p>
Our new release, "SECOND", is now the current release, but we
can also see that our "FIRST" release is still permanent. This
@@ -420,12 +420,12 @@ os> <input>/usr/local/erl-target/bin/to_erl /tmp/erlang.pipe.2</input></pre>
</p>
<pre>
3> <input>release_handler:which_releases().</input>
-<output>[{"MYSYSTEM","SECOND",
+[{"MYSYSTEM","SECOND",
["kernel-3.0","stdlib-2.0","sasl-2.4","pea-2.0"],
permanent},
{"MYSYSTEM","FIRST",
["kernel-2.16.4","stdlib-1.19.4","sasl-2.3.4","pea-1.0"],
- old}]</output></pre>
+ old}]</pre>
<p>
We see that the new release version is <c>permanent</c>, so
it would be safe to restart the node.</p>
diff --git a/system/doc/system_principles/error_logging.xml b/system/doc/system_principles/error_logging.xml
index 024137a430..c99d59ddb7 100644
--- a/system/doc/system_principles/error_logging.xml
+++ b/system/doc/system_principles/error_logging.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2013</year>
+ <year>2003</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/system_principles/part.xml b/system/doc/system_principles/part.xml
index 1557b5ff62..1b87ecd350 100644
--- a/system/doc/system_principles/part.xml
+++ b/system/doc/system_principles/part.xml
@@ -4,7 +4,7 @@
<part xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>1997</year><year>2014</year>
+ <year>1997</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/system_principles/upgrade.xml b/system/doc/system_principles/upgrade.xml
index 173e46185c..c491bd855e 100644
--- a/system/doc/system_principles/upgrade.xml
+++ b/system/doc/system_principles/upgrade.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2014</year>
+ <year>2014</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/system_principles/versions.xml b/system/doc/system_principles/versions.xml
index ee104a8302..b9f7fa4bf6 100644
--- a/system/doc/system_principles/versions.xml
+++ b/system/doc/system_principles/versions.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2014</year>
+ <year>2014</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -57,11 +57,11 @@
<p>In an OTP source code tree, the OTP version can be read from
the text file <c>&lt;OTP source root&gt;/OTP_VERSION</c>. The
absolute path to the file can be constructed by calling
- <c>filename:join([<seealso marker="kernel:code#root_dir/0">code:root_dir()</seealso>, "OTP_VERSION"])</c>.</p>
+ <c>filename:join([</c><seealso marker="kernel:code#root_dir/0"><c>code:root_dir()</c></seealso><c>, "OTP_VERSION"])</c>.</p>
<p>In an installed OTP development system, the OTP version can be read
from the text file <c>&lt;OTP installation root&gt;/releases/&lt;OTP release number&gt;/OTP_VERSION</c>.
The absolute path to the file can by constructed by calling
- <c>filename:join([<seealso marker="kernel:code#root_dir/0">code:root_dir()</seealso>, "releases", <seealso marker="erts:erlang#system_info_otp_release"> erlang:system_info(otp_release)</seealso>, "OTP_VERSION"]).</c></p>
+ <c>filename:join([</c><seealso marker="kernel:code#root_dir/0"><c>code:root_dir()</c></seealso><c>, "releases", </c><seealso marker="erts:erlang#system_info_otp_release"><c>erlang:system_info(otp_release)</c></seealso><c>, "OTP_VERSION"]).</c></p>
<p>If the version read from the <c>OTP_VERSION</c> file in a
development system has a <c>**</c> suffix, the system has been
patched using the
diff --git a/system/doc/system_principles/xmlfiles.mk b/system/doc/system_principles/xmlfiles.mk
index fcc1fc886f..c3c3bb4731 100644
--- a/system/doc/system_principles/xmlfiles.mk
+++ b/system/doc/system_principles/xmlfiles.mk
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2009-2014. All Rights Reserved.
+# Copyright Ericsson AB 2009-2016. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/system/doc/top/Makefile b/system/doc/top/Makefile
index 7e3041ce1e..116ec688fa 100644
--- a/system/doc/top/Makefile
+++ b/system/doc/top/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1999-2013. All Rights Reserved.
+# Copyright Ericsson AB 1999-2016. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -35,7 +35,7 @@ RELSYSDIR = "$(RELEASE_PATH)/doc"
GIF_FILES =
-INFO_FILES = ../../README ../../COPYRIGHT PR.template
+INFO_FILES = ../../../README.md ../../COPYRIGHT PR.template
TOPDOCDIR=.
@@ -74,6 +74,7 @@ XML_FILES = \
BOOK_FILES = book.xml
+XMLLINT_SRCDIRS= ../installation_guide:../system_principles:../embedded:../getting_started:../reference_manual:../programming_examples:../efficiency_guide:../tutorial:../design_principles:../oam
HTMLDIR= ../html
PDFREFDIR= pdf
@@ -120,10 +121,11 @@ $(HTMLDIR)/index.html + $(HTMLDIR)/applications.html: $(INDEX_SCRIPT) $(TEMPLATE
# Check if we are building the index from source or an installed release
if test "$$RELEASE_ROOT" = "" ; then \
$(ERL) -noshell -pa $(EBIN) -s erl_html_tools top_index src $(ERL_TOP) \
- $(HTMLDIR) $(SYSTEM_VSN) -s erlang halt ;\
+ $(HTMLDIR) `cat "$(ERL_TOP)/OTP_VERSION"` -s erlang halt ;\
else \
$(ERL) -noshell -pa $(EBIN) -s erl_html_tools top_index rel $(RELEASE_ROOT) \
- $(HTMLDIR) $(SYSTEM_VSN) -s erlang halt ;\
+ $(HTMLDIR) `cat "$(RELEASE_ROOT)/releases/$(SYSTEM_VSN)/OTP_VERSION"` \
+ -s erlang halt ;\
fi
diff --git a/system/doc/top/book.xml b/system/doc/top/book.xml
index 7bbeb38472..c94b0f24d6 100644
--- a/system/doc/top/book.xml
+++ b/system/doc/top/book.xml
@@ -4,7 +4,7 @@
<book xmlns:xi="http://www.w3.org/2001/XInclude">
<header titlestyle="normal">
<copyright>
- <year>1997</year><year>2013</year>
+ <year>1997</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/top/src/erl_html_tools.erl b/system/doc/top/src/erl_html_tools.erl
index dddf025020..d55c2e1164 100644
--- a/system/doc/top/src/erl_html_tools.erl
+++ b/system/doc/top/src/erl_html_tools.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -54,24 +54,24 @@ top_index() ->
top_index(src, Value, filename:join(Value, "doc"), RelName)
end.
-top_index([src, RootDir, DestDir, OtpRel])
- when is_atom(RootDir), is_atom(DestDir), is_atom(OtpRel) ->
- top_index(src, atom_to_list(RootDir), atom_to_list(DestDir), atom_to_list(OtpRel));
-top_index([rel, RootDir, DestDir, OtpRel])
- when is_atom(RootDir), is_atom(DestDir), is_atom(OtpRel) ->
- top_index(rel, atom_to_list(RootDir), atom_to_list(DestDir), atom_to_list(OtpRel));
+top_index([src, RootDir, DestDir, OtpBaseVsn])
+ when is_atom(RootDir), is_atom(DestDir), is_atom(OtpBaseVsn) ->
+ top_index(src, atom_to_list(RootDir), atom_to_list(DestDir), atom_to_list(OtpBaseVsn));
+top_index([rel, RootDir, DestDir, OtpBaseVsn])
+ when is_atom(RootDir), is_atom(DestDir), is_atom(OtpBaseVsn) ->
+ top_index(rel, atom_to_list(RootDir), atom_to_list(DestDir), atom_to_list(OtpBaseVsn));
top_index(RootDir) when is_atom(RootDir) ->
{_,RelName} = init:script_id(),
top_index(rel, RootDir, filename:join(RootDir, "doc"), RelName).
-top_index(Source, RootDir, DestDir, OtpRel) ->
+top_index(Source, RootDir, DestDir, OtpBaseVsn) ->
report("****\nRootDir: ~p", [RootDir]),
report("****\nDestDir: ~p", [DestDir]),
- report("****\nOtpRel: ~p", [OtpRel]),
+ report("****\nOtpBaseVsn: ~p", [OtpBaseVsn]),
- put(otp_release, OtpRel),
+ put(otp_base_vsn, OtpBaseVsn),
Templates = find_templates(["","templates",DestDir]),
report("****\nTemplates: ~p", [Templates]),
@@ -81,9 +81,9 @@ top_index(Source, RootDir, DestDir, OtpRel) ->
report("****\nGroups: ~p", [Groups]),
process_templates(Templates, DestDir, Groups).
-top_index_silent(RootDir, DestDir, OtpRel) ->
+top_index_silent(RootDir, DestDir, OtpBaseVsn) ->
put(silent,true),
- Result = top_index(rel, RootDir, DestDir, OtpRel),
+ Result = top_index(rel, RootDir, DestDir, OtpBaseVsn),
erase(silent),
Result.
@@ -361,7 +361,7 @@ subst_template_1(Group, Stream, Info) ->
case file:read(Stream, 100000) of
{ok, Template} ->
Fun = fun(Match, _) -> {subst(Match, Info, Group),Info} end,
- gsub(Template, "#[A-Za-z0-9]+#", Fun, Info);
+ gsub(Template, "#[A-Za-z_0-9]+#", Fun, Info);
{error, Reason} ->
{error, Reason}
end.
@@ -379,8 +379,8 @@ get_version(Info) ->
""
end.
-subst("#release#", _Info, _Group) ->
- get(otp_release);
+subst("#otp_base_vsn#", _Info, _Group) ->
+ get(otp_base_vsn);
subst("#version#", Info, _Group) ->
get_version(Info);
subst("#copyright#", _Info, _Group) ->
diff --git a/system/doc/top/src/erlresolvelinks.erl b/system/doc/top/src/erlresolvelinks.erl
index 7946fd4bea..cfe8d0fa0b 100644
--- a/system/doc/top/src/erlresolvelinks.erl
+++ b/system/doc/top/src/erlresolvelinks.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/system/doc/top/src/otp_man_index.erl b/system/doc/top/src/otp_man_index.erl
index 753e952ecb..12aaba1423 100644
--- a/system/doc/top/src/otp_man_index.erl
+++ b/system/doc/top/src/otp_man_index.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
diff --git a/system/doc/top/templates/applications.html.src b/system/doc/top/templates/applications.html.src
index 4be969f9d1..1f73c44d69 100644
--- a/system/doc/top/templates/applications.html.src
+++ b/system/doc/top/templates/applications.html.src
@@ -2,7 +2,7 @@
<!--
%CopyrightBegin%
-Copyright Ericsson AB 2009-2010. All Rights Reserved.
+Copyright Ericsson AB 2009-2016. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/system/doc/top/templates/index.html.src b/system/doc/top/templates/index.html.src
index bdac3895b0..d2a6736d34 100644
--- a/system/doc/top/templates/index.html.src
+++ b/system/doc/top/templates/index.html.src
@@ -2,7 +2,7 @@
<!--
%CopyrightBegin%
-Copyright Ericsson AB 2009-2014. All Rights Reserved.
+Copyright Ericsson AB 2009-2016. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -22,7 +22,7 @@ limitations under the License.
<html>
<head>
<link rel="stylesheet" href="otp_doc.css" type="text/css"/>
- <title>Erlang/OTP #release#</title>
+ <title>Erlang/OTP #otp_base_vsn#</title>
<script id="js" type="text/javascript" language="JavaScript" src="js/flipmenu/flipmenu.js">
@@ -36,7 +36,7 @@ limitations under the License.
<div id="leftnav">
<div class="innertube">
<img alt="Erlang logo" src="erlang-logo.png"/ >
-<!-- small><a href="glossary.html">Glossary</a> |-->
+<p/>
<small><a href="applications.html">Applications</a><br>
<a href="man_index.html">Modules</a></small>
<p/>
@@ -74,7 +74,7 @@ limitations under the License.
<div id="content">
<div class="innertube">
<center>
-<font size="+1"><b>Erlang/OTP #release#</b></font><br>
+<font size="+1"><b>Erlang/OTP #otp_base_vsn#</b></font><br>
</center>
<center>
<p>
@@ -108,7 +108,7 @@ In addition to the documentation here Erlang is described in several recent book
<a href="http://shop.oreilly.com/product/0636920025818.do">"Introducing Erlang"</a> from O'Reilly.
</li>
<li>
-<a href="http://www.nostarch.com/erlang">"Learn You Some Erlang for Great Good!"</a> from nostarch.
+<a href="http://www.nostarch.com/erlang">"Learn You Some Erlang for Great Good!"</a> from No Starch Press.
</li>
<li>
<a href="http://oreilly.com/catalog/9780596518189">"Erlang Programming"</a> from O'Reilly.
@@ -119,6 +119,9 @@ In addition to the documentation here Erlang is described in several recent book
<li>
<a href="http://www.manning.com/logan">"Erlang and OTP in Action"</a> from Manning.
</li>
+<li>
+<a href="http://shop.oreilly.com/product/0636920024149.do">"Designing for Scalability with Erlang/OTP"</a> from O'Reilly.
+</li>
</ul>
<p>
These books are highly recommended as a start for learning Erlang.
@@ -129,14 +132,15 @@ href="applications.html">applications</a>. An application normally contains
Erlang <a href="man_index.html">modules</a>. Some OTP applications,
such as the C interface <em>erl_interface</em>, are written in other languages and have no Erlang
modules.
+<p></p>
+</li>
-<p>
<li>On a Unix system you can view the manual pages from the command
line using
<pre>
% erl -man &lt;module&gt;
</pre>
-<p>
+</li>
<li> You can of course use any editor you like to write Erlang
programs, but if you use Emacs there exists editing support such as
@@ -145,10 +149,10 @@ verification, comment support including paragraph filling, skeletons,
tags support and more. See the <a href="#tools#/index.html">
Tools</a> application for details.
<p>
-There is also an
-<a href="http://erlide.org/index.html">
-Erlang plugin (ErlIDE) for Eclipse</a> if you prefer a more graphical
-environment. ErlIDE is under active development with new features in almost every release.
+There are also Erlang plugins for
+<a href="http://erlide.org/index.html">Eclipse (ErlIDE)</a> and
+<a href="http://ignatov.github.io/intellij-erlang/">IntelliJ IDEA</a>
+if you prefer a more graphical environment, which are both under active development.
<li>When developing with Erlang/OTP you usually test your programs
from the interactive shell (see <a href="getting_started/users_guide.html">
Getting Started With Erlang</a>) where you can call individual
@@ -161,23 +165,27 @@ module and function name completion (tab) if the module is loaded.
<li>OpenSource users can ask questions
and share experiences on the <a href="http://www.erlang.org/static/doc/mailinglist.html">
-Erlang questions mailing list</a>. <p>
+Erlang questions mailing list</a>.
+<p></p>
+</li>
<li>Before asking a question you can browse the <a
href="http://www.erlang.org/pipermail/erlang-questions/">
mailing list archive</a> and read the <a
href="http://www.erlang.org/faq/faq.html" >Frequently
-Asked Questions</a>. <p>
+Asked Questions</a>.
+<p></p>
+</li>
<li>Additional information and links of interest for Erlang programmers can be found on the Erlang Open Source site
<a href="http://www.erlang.org/">http://www.erlang.org</a>.
-<p>
+</li>
</ul>
<center>
<small>
-Copyright &copy; 1999-2013
+Copyright &copy; 1999-2016
<a href="http://www.ericsson.com">Ericsson AB</a>
</small>
</center>
diff --git a/system/doc/tutorial/Makefile b/system/doc/tutorial/Makefile
index 868e79cd83..5deea41f0a 100644
--- a/system/doc/tutorial/Makefile
+++ b/system/doc/tutorial/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2000-2012. All Rights Reserved.
+# Copyright Ericsson AB 2000-2016. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/system/doc/tutorial/appendix.xmlsrc b/system/doc/tutorial/appendix.xmlsrc
index 52c24c1b67..4be6c91fe9 100644
--- a/system/doc/tutorial/appendix.xmlsrc
+++ b/system/doc/tutorial/appendix.xmlsrc
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2000</year><year>2013</year>
+ <year>2000</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/tutorial/book.xml b/system/doc/tutorial/book.xml
index 81530f25eb..1841a2df60 100644
--- a/system/doc/tutorial/book.xml
+++ b/system/doc/tutorial/book.xml
@@ -4,7 +4,7 @@
<book xmlns:xi="http://www.w3.org/2001/XInclude">
<header titlestyle="normal">
<copyright>
- <year>2000</year><year>2013</year>
+ <year>2000</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/tutorial/c_port.xmlsrc b/system/doc/tutorial/c_port.xmlsrc
index 695f16515d..3c3bc48044 100644
--- a/system/doc/tutorial/c_port.xmlsrc
+++ b/system/doc/tutorial/c_port.xmlsrc
@@ -98,11 +98,11 @@ loop(Port) ->
{call, Caller, Msg} ->
Port ! {self(), {command, encode(Msg)}},
receive
- {Port, {data, Data}} ->
+ {Port, {data, Data}} ->
Caller ! {complex, decode(Data)}
end,
loop(Port)
- end.</pre>
+ end.</pre>
<p>Assuming that both the arguments and the results from the C
functions are less than 256, a simple encoding/decoding scheme
is employed. In this scheme, <c>foo</c> is represented by byte
diff --git a/system/doc/tutorial/distribution.xml b/system/doc/tutorial/distribution.xml
index 40d60acb3a..b489410841 100644
--- a/system/doc/tutorial/distribution.xml
+++ b/system/doc/tutorial/distribution.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2000</year><year>2013</year>
+ <year>2000</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/tutorial/ei.c b/system/doc/tutorial/ei.c
index b234a00768..c33e3fb78e 100644
--- a/system/doc/tutorial/ei.c
+++ b/system/doc/tutorial/ei.c
@@ -21,7 +21,7 @@ int main() {
if (strncmp(ERL_ATOM_PTR(fnp), "foo", 3) == 0) {
res = foo(ERL_INT_VALUE(argp));
- } else if (strncmp(ERL_ATOM_PTR(fnp), "bar", 17) == 0) {
+ } else if (strncmp(ERL_ATOM_PTR(fnp), "bar", 3) == 0) {
res = bar(ERL_INT_VALUE(argp));
}
diff --git a/system/doc/tutorial/example.xmlsrc b/system/doc/tutorial/example.xmlsrc
index d49c7fe88c..91f09ec522 100644
--- a/system/doc/tutorial/example.xmlsrc
+++ b/system/doc/tutorial/example.xmlsrc
@@ -11,7 +11,7 @@
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
@@ -19,7 +19,7 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-
+
</legalnotice>
<title>Problem Example</title>
@@ -39,7 +39,7 @@
<codeinclude file="complex.c" tag="" type="none"></codeinclude>
<p>The functions are deliberately kept as simple as possible, for
readability reasons.</p>
- <p>From an Erlang perspektive, it is preferable to be able to call
+ <p>From an Erlang perspective, it is preferable to be able to call
<c>foo</c> and <c>bar</c> without having to bother about that
they are C functions:</p>
<pre>
diff --git a/system/doc/tutorial/part.xml b/system/doc/tutorial/part.xml
index 5216d1653d..4a66f0cb22 100644
--- a/system/doc/tutorial/part.xml
+++ b/system/doc/tutorial/part.xml
@@ -4,7 +4,7 @@
<part xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>2000</year><year>2013</year>
+ <year>2000</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/tutorial/xmlfiles.mk b/system/doc/tutorial/xmlfiles.mk
index 28b66f232d..f8ed7be064 100644
--- a/system/doc/tutorial/xmlfiles.mk
+++ b/system/doc/tutorial/xmlfiles.mk
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2009-2010. All Rights Reserved.
+# Copyright Ericsson AB 2009-2016. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.