aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.in19
-rw-r--r--erts/configure.in1
-rw-r--r--erts/doc/src/erlang.xml8
-rw-r--r--erts/emulator/beam/beam_bif_load.c12
-rw-r--r--erts/emulator/beam/bif.c24
-rw-r--r--erts/emulator/beam/big.c6
-rw-r--r--erts/emulator/beam/big.h4
-rw-r--r--erts/emulator/beam/erl_alloc.c190
-rw-r--r--erts/emulator/beam/erl_alloc.types57
-rw-r--r--erts/emulator/beam/erl_alloc_util.c28
-rw-r--r--erts/emulator/beam/erl_alloc_util.h3
-rw-r--r--erts/emulator/beam/erl_db_hash.c9
-rw-r--r--erts/emulator/beam/erl_db_tree.c62
-rw-r--r--erts/emulator/beam/erl_lock_check.c10
-rw-r--r--erts/emulator/beam/erl_lock_check.h2
-rw-r--r--erts/emulator/beam/erl_printf_term.c101
-rw-r--r--erts/emulator/beam/erl_printf_term.h4
-rw-r--r--erts/emulator/beam/erl_process.c70
-rw-r--r--erts/emulator/beam/erl_process.h4
-rw-r--r--erts/emulator/sys/common/erl_mseg.c35
-rw-r--r--erts/emulator/sys/common/erl_mseg.h11
-rw-r--r--erts/emulator/test/process_SUITE.erl40
-rwxr-xr-xerts/etc/win32/nsis/find_redist.sh15
-rw-r--r--erts/include/internal/erl_printf_format.h2
-rw-r--r--erts/lib_src/common/erl_printf_format.c29
-rw-r--r--lib/asn1/test/test_inline.erl6
-rw-r--r--lib/et/src/et_wx_contents_viewer.erl4
-rw-r--r--lib/et/src/et_wx_viewer.erl6
-rw-r--r--lib/kernel/doc/specs/.gitignore1
-rw-r--r--lib/kernel/doc/src/Makefile40
-rw-r--r--lib/kernel/doc/src/application.xml234
-rw-r--r--lib/kernel/doc/src/auth.xml51
-rw-r--r--lib/kernel/doc/src/code.xml6
-rw-r--r--lib/kernel/doc/src/disk_log.xml451
-rw-r--r--lib/kernel/doc/src/erl_boot_server.xml44
-rw-r--r--lib/kernel/doc/src/erl_ddll.xml129
-rw-r--r--lib/kernel/doc/src/error_handler.xml44
-rw-r--r--lib/kernel/doc/src/error_logger.xml135
-rw-r--r--lib/kernel/doc/src/file.xml895
-rw-r--r--lib/kernel/doc/src/gen_sctp.xml237
-rw-r--r--lib/kernel/doc/src/gen_tcp.xml163
-rw-r--r--lib/kernel/doc/src/gen_udp.xml101
-rw-r--r--lib/kernel/doc/src/global.xml176
-rw-r--r--lib/kernel/doc/src/global_group.xml157
-rw-r--r--lib/kernel/doc/src/heart.xml16
-rw-r--r--lib/kernel/doc/src/inet.xml193
-rw-r--r--lib/kernel/doc/src/inet_res.xml271
-rw-r--r--lib/kernel/doc/src/net_adm.xml74
-rw-r--r--lib/kernel/doc/src/net_kernel.xml90
-rw-r--r--lib/kernel/doc/src/os.xml44
-rw-r--r--lib/kernel/doc/src/pg2.xml66
-rw-r--r--lib/kernel/doc/src/rpc.xml330
-rw-r--r--lib/kernel/doc/src/seq_trace.xml95
-rw-r--r--lib/kernel/doc/src/specs.xml33
-rw-r--r--lib/kernel/doc/src/wrap_log_reader.xml66
-rw-r--r--lib/kernel/include/inet.hrl15
-rw-r--r--lib/kernel/src/application.erl172
-rw-r--r--lib/kernel/src/auth.erl16
-rw-r--r--lib/kernel/src/disk_log.erl252
-rw-r--r--lib/kernel/src/disk_log.hrl24
-rw-r--r--lib/kernel/src/erl_boot_server.erl28
-rw-r--r--lib/kernel/src/erl_ddll.erl49
-rw-r--r--lib/kernel/src/error_handler.erl13
-rw-r--r--lib/kernel/src/error_logger.erl79
-rw-r--r--lib/kernel/src/file.erl375
-rw-r--r--lib/kernel/src/gen_sctp.erl148
-rw-r--r--lib/kernel/src/gen_tcp.erl82
-rw-r--r--lib/kernel/src/gen_udp.erl52
-rw-r--r--lib/kernel/src/global.erl92
-rw-r--r--lib/kernel/src/global_group.erl58
-rw-r--r--lib/kernel/src/global_search.erl5
-rw-r--r--lib/kernel/src/heart.erl10
-rw-r--r--lib/kernel/src/inet.erl96
-rw-r--r--lib/kernel/src/inet_res.erl176
-rw-r--r--lib/kernel/src/inet_udp.erl6
-rw-r--r--lib/kernel/src/net_adm.erl41
-rw-r--r--lib/kernel/src/net_kernel.erl37
-rw-r--r--lib/kernel/src/os.erl23
-rw-r--r--lib/kernel/src/pg2.erl68
-rw-r--r--lib/kernel/src/rpc.erl192
-rw-r--r--lib/kernel/src/seq_trace.erl44
-rw-r--r--lib/kernel/src/wrap_log_reader.erl35
-rw-r--r--lib/mnesia/src/mnesia_dumper.erl8
-rw-r--r--lib/mnesia/src/mnesia_schema.erl5
-rw-r--r--lib/mnesia/test/.gitignore9
-rw-r--r--lib/mnesia/test/mnesia_durability_test.erl4
-rw-r--r--lib/mnesia/test/mnesia_qlc_test.erl3
-rw-r--r--lib/mnesia/test/mnesia_test_lib.erl90
-rw-r--r--lib/mnesia/test/mnesia_trans_access_test.erl36
-rw-r--r--lib/mnesia/test/mt.erl15
-rw-r--r--lib/stdlib/include/zip.hrl4
-rw-r--r--lib/stdlib/src/array.erl111
-rw-r--r--lib/stdlib/src/base64.erl24
-rw-r--r--lib/stdlib/src/beam_lib.erl117
-rw-r--r--lib/stdlib/src/binary.erl37
-rw-r--r--lib/stdlib/src/c.erl66
-rw-r--r--lib/stdlib/src/calendar.erl91
-rw-r--r--lib/stdlib/src/dets.erl301
-rw-r--r--lib/stdlib/src/dict.erl99
-rw-r--r--lib/stdlib/src/digraph.erl159
-rw-r--r--lib/stdlib/src/digraph_utils.erl84
-rw-r--r--lib/stdlib/src/epp.erl43
-rw-r--r--lib/stdlib/src/erl_eval.erl134
-rw-r--r--lib/stdlib/src/erl_expand_records.erl6
-rw-r--r--lib/stdlib/src/erl_internal.erl39
-rw-r--r--lib/stdlib/src/erl_lint.erl31
-rw-r--r--lib/stdlib/src/erl_parse.yrl39
-rw-r--r--lib/stdlib/src/erl_pp.erl65
-rw-r--r--lib/stdlib/src/erl_scan.erl115
-rw-r--r--lib/stdlib/src/ets.erl148
-rw-r--r--lib/stdlib/src/file_sorter.erl119
-rw-r--r--lib/stdlib/src/filelib.erl39
-rw-r--r--lib/stdlib/src/filename.erl84
-rw-r--r--lib/stdlib/src/gb_sets.erl147
-rw-r--r--lib/stdlib/src/gb_trees.erl109
-rw-r--r--lib/stdlib/src/gen_event.erl11
-rw-r--r--lib/stdlib/src/io.erl195
-rw-r--r--lib/stdlib/src/io_lib.erl78
-rw-r--r--lib/stdlib/src/io_lib_fread.erl41
-rw-r--r--lib/stdlib/src/lib.erl20
-rw-r--r--lib/stdlib/src/lists.erl425
-rw-r--r--lib/stdlib/src/log_mf_h.erl21
-rw-r--r--lib/stdlib/src/ms_transform.erl16
-rw-r--r--lib/stdlib/src/orddict.erl98
-rw-r--r--lib/stdlib/src/ordsets.erl72
-rw-r--r--lib/stdlib/src/pg.erl28
-rw-r--r--lib/stdlib/src/pool.erl24
-rw-r--r--lib/stdlib/src/proc_lib.erl138
-rw-r--r--lib/stdlib/src/proplists.erl151
-rw-r--r--lib/stdlib/src/qlc.erl304
-rw-r--r--lib/stdlib/src/qlc_pt.erl18
-rw-r--r--lib/stdlib/src/queue.erl123
-rw-r--r--lib/stdlib/src/random.erl24
-rw-r--r--lib/stdlib/src/re.erl47
-rw-r--r--lib/stdlib/src/regexp.erl69
-rw-r--r--lib/stdlib/src/sets.erl74
-rw-r--r--lib/stdlib/src/shell.erl23
-rw-r--r--lib/stdlib/src/slave.erl52
-rw-r--r--lib/stdlib/src/sofs.erl545
-rw-r--r--lib/stdlib/src/string.erl175
-rw-r--r--lib/stdlib/src/supervisor.erl98
-rw-r--r--lib/stdlib/src/supervisor_bridge.erl18
-rw-r--r--lib/stdlib/src/sys.erl182
-rw-r--r--lib/stdlib/src/timer.erl142
-rw-r--r--lib/stdlib/src/unicode.erl51
-rw-r--r--lib/stdlib/src/win32reg.erl70
-rw-r--r--lib/stdlib/src/zip.erl185
-rw-r--r--lib/stdlib/test/erl_eval_SUITE.erl2
-rw-r--r--lib/stdlib/test/erl_pp_SUITE.erl2
-rw-r--r--lib/stdlib/test/sofs_SUITE.erl27
-rw-r--r--lib/stdlib/test/timer_simple_SUITE.erl31
151 files changed, 8605 insertions, 4448 deletions
diff --git a/Makefile.in b/Makefile.in
index ca92bf604d..b17713f182 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1998-2010. All Rights Reserved.
+# Copyright Ericsson AB 1998-2011. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
@@ -396,20 +396,25 @@ endif
release_docs docs: mod2app
ifeq ($(OTP_SMALL_BUILD),true)
cd $(ERL_TOP)/lib && \
- ERL_TOP=$(ERL_TOP) $(MAKE) TESTROOT=$(RELEASE_ROOT) $@
+ PATH=$(ERL_TOP)/bin:$${PATH} ERL_TOP=$(ERL_TOP) \
+ $(MAKE) TESTROOT=$(RELEASE_ROOT) $@
else
cd $(ERL_TOP)/lib && \
- ERL_TOP=$(ERL_TOP) $(MAKE) BUILD_ALL=1 TESTROOT=$(RELEASE_ROOT) $@
+ PATH=$(ERL_TOP)/bin:$${PATH} ERL_TOP=$(ERL_TOP) \
+ $(MAKE) BUILD_ALL=1 TESTROOT=$(RELEASE_ROOT) $@
cd $(ERL_TOP)/lib/dialyzer && \
- ERL_TOP=$(ERL_TOP) $(MAKE) BUILD_ALL=1 TESTROOT=$(RELEASE_ROOT) $@
+ PATH=$(ERL_TOP)/bin:$${PATH} ERL_TOP=$(ERL_TOP) \
+ $(MAKE) BUILD_ALL=1 TESTROOT=$(RELEASE_ROOT) $@
endif
cd $(ERL_TOP)/erts && \
- ERL_TOP=$(ERL_TOP) $(MAKE) BUILD_ALL=1 TESTROOT=$(RELEASE_ROOT) $@
+ PATH=$(ERL_TOP)/bin:$${PATH} ERL_TOP=$(ERL_TOP) \
+ $(MAKE) BUILD_ALL=1 TESTROOT=$(RELEASE_ROOT) $@
cd $(ERL_TOP)/system/doc && \
+ PATH=$(ERL_TOP)/bin:$${PATH} \
ERL_TOP=$(ERL_TOP) $(MAKE) TESTROOT=$(RELEASE_ROOT) $@
-mod2app:
- $(ERL_TOP)/lib/erl_docgen/priv/bin/xref_mod_app.escript -topdir $(ERL_TOP) -outfile $(ERL_TOP)/make/$(TARGET)/mod2app.xml
+mod2app:
+ PATH=$(ERL_TOP)/bin:$${PATH} escript $(ERL_TOP)/lib/erl_docgen/priv/bin/xref_mod_app.escript -topdir $(ERL_TOP) -outfile $(ERL_TOP)/make/$(TARGET)/mod2app.xml
# ----------------------------------------------------------------------
ERLANG_EARS=$(BOOTSTRAP_ROOT)/bootstrap/erts
diff --git a/erts/configure.in b/erts/configure.in
index 31d1d55b8a..e4c6a7852f 100644
--- a/erts/configure.in
+++ b/erts/configure.in
@@ -769,6 +769,7 @@ if test "$enable_halfword_emulator" = "yes"; then
if test "$ARCH" = "amd64"; then
AC_DEFINE(HALFWORD_HEAP_EMULATOR, [1],
[Define if building a halfword-heap 64bit emulator])
+ ENABLE_ALLOC_TYPE_VARS="$ENABLE_ALLOC_TYPE_VARS halfword"
AC_MSG_RESULT([yes])
else
AC_MSG_ERROR(no; halfword emulator not supported on this architecture)
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index 19f501391f..f98e15cb52 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -2356,6 +2356,14 @@ os_prompt%</pre>
<seealso marker="tools:instrument">instrument(3)</seealso>
and/or <seealso marker="erts:erl">erl(1)</seealso>.</p>
</item>
+ <tag><c>low</c></tag>
+ <item>
+ <p>Only on 64-bit halfword emulator.</p>
+ <p>The total amount of memory allocated in low memory areas
+ that are restricted to less than 4 Gb even though
+ the system may have more physical memory.</p>
+ <p>May be removed in future releases of halfword emulator.</p>
+ </item>
</taglist>
<note>
<p>The <c>system</c> value is not complete. Some allocated
diff --git a/erts/emulator/beam/beam_bif_load.c b/erts/emulator/beam/beam_bif_load.c
index 1ca405961f..1dbf6f9b92 100644
--- a/erts/emulator/beam/beam_bif_load.c
+++ b/erts/emulator/beam/beam_bif_load.c
@@ -175,8 +175,12 @@ check_process_code_2(BIF_ALIST_2)
Eterm res;
if (internal_pid_index(BIF_ARG_1) >= erts_max_processes)
goto error;
- rp = erts_pid2proc_not_running(BIF_P, ERTS_PROC_LOCK_MAIN,
- BIF_ARG_1, ERTS_PROC_LOCK_MAIN);
+#ifdef ERTS_SMP
+ rp = erts_pid2proc_suspend(BIF_P, ERTS_PROC_LOCK_MAIN,
+ BIF_ARG_1, ERTS_PROC_LOCK_MAIN);
+#else
+ rp = erts_pid2proc(BIF_P, 0, BIF_ARG_1, 0);
+#endif
if (!rp) {
BIF_RET(am_false);
}
@@ -187,8 +191,10 @@ check_process_code_2(BIF_ALIST_2)
modp = erts_get_module(BIF_ARG_2);
res = check_process_code(rp, modp);
#ifdef ERTS_SMP
- if (BIF_P != rp)
+ if (BIF_P != rp) {
+ erts_resume(rp, ERTS_PROC_LOCK_MAIN);
erts_smp_proc_unlock(rp, ERTS_PROC_LOCK_MAIN);
+ }
#endif
BIF_RET(res);
}
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index b3325d635b..8c35644125 100644
--- a/erts/emulator/beam/bif.c
+++ b/erts/emulator/beam/bif.c
@@ -3215,20 +3215,32 @@ BIF_RETTYPE garbage_collect_1(BIF_ALIST_1)
BIF_ERROR(BIF_P, BADARG);
}
- rp = erts_pid2proc_not_running(BIF_P, ERTS_PROC_LOCK_MAIN,
+ if (BIF_P->id == BIF_ARG_1)
+ rp = BIF_P;
+ else {
+#ifdef ERTS_SMP
+ rp = erts_pid2proc_suspend(BIF_P, ERTS_PROC_LOCK_MAIN,
BIF_ARG_1, ERTS_PROC_LOCK_MAIN);
- if (!rp)
- BIF_RET(am_false);
- if (rp == ERTS_PROC_LOCK_BUSY)
- ERTS_BIF_YIELD1(bif_export[BIF_garbage_collect_1], BIF_P, BIF_ARG_1);
+ if (rp == ERTS_PROC_LOCK_BUSY)
+ ERTS_BIF_YIELD1(bif_export[BIF_garbage_collect_1], BIF_P, BIF_ARG_1);
+#else
+ rp = erts_pid2proc(BIF_P, 0, BIF_ARG_1, 0);
+#endif
+ if (!rp)
+ BIF_RET(am_false);
+ }
/* The GC cost is taken for the process executing this BIF. */
FLAGS(rp) |= F_NEED_FULLSWEEP;
reds = erts_garbage_collect(rp, 0, rp->arg_reg, rp->arity);
- if (BIF_P != rp)
+#ifdef ERTS_SMP
+ if (BIF_P != rp) {
+ erts_resume(rp, ERTS_PROC_LOCK_MAIN);
erts_smp_proc_unlock(rp, ERTS_PROC_LOCK_MAIN);
+ }
+#endif
BIF_RET2(am_true, reds);
}
diff --git a/erts/emulator/beam/big.c b/erts/emulator/beam/big.c
index f47f5a9c0c..d18de9ae5d 100644
--- a/erts/emulator/beam/big.c
+++ b/erts/emulator/beam/big.c
@@ -1588,7 +1588,7 @@ big_to_double(Wterm x, double* resp)
/*
** Estimate the number of decimal digits (include sign)
*/
-int big_decimal_estimate(Eterm x)
+int big_decimal_estimate(Wterm x)
{
Eterm* xp = big_val(x);
int lg = I_lg(BIG_V(xp), BIG_SIZE(xp));
@@ -1602,7 +1602,7 @@ int big_decimal_estimate(Eterm x)
** Convert a bignum into a string of decimal numbers
*/
-static void write_big(Eterm x, void (*write_func)(void *, char), void *arg)
+static void write_big(Wterm x, void (*write_func)(void *, char), void *arg)
{
Eterm* xp = big_val(x);
ErtsDigit* dx = BIG_V(xp);
@@ -1681,7 +1681,7 @@ write_string(void *arg, char c)
*(--(*((char **) arg))) = c;
}
-char *erts_big_to_string(Eterm x, char *buf, Uint buf_sz)
+char *erts_big_to_string(Wterm x, char *buf, Uint buf_sz)
{
char *big_str = buf + buf_sz - 1;
*big_str = '\0';
diff --git a/erts/emulator/beam/big.h b/erts/emulator/beam/big.h
index f28a390aea..2afc37004f 100644
--- a/erts/emulator/beam/big.h
+++ b/erts/emulator/beam/big.h
@@ -114,9 +114,9 @@ typedef Uint dsize_t; /* Vector size type */
#endif
-int big_decimal_estimate(Eterm);
+int big_decimal_estimate(Wterm);
Eterm erts_big_to_list(Eterm, Eterm**);
-char *erts_big_to_string(Eterm x, char *buf, Uint buf_sz);
+char *erts_big_to_string(Wterm x, char *buf, Uint buf_sz);
Eterm small_times(Sint, Sint, Eterm*);
diff --git a/erts/emulator/beam/erl_alloc.c b/erts/emulator/beam/erl_alloc.c
index 673eac7fea..cda404af5e 100644
--- a/erts/emulator/beam/erl_alloc.c
+++ b/erts/emulator/beam/erl_alloc.c
@@ -90,6 +90,10 @@ typedef union {
static ErtsAllocatorState_t sl_alloc_state;
static ErtsAllocatorState_t std_alloc_state;
static ErtsAllocatorState_t ll_alloc_state;
+#if HALFWORD_HEAP
+static ErtsAllocatorState_t std_alloc_low_state;
+static ErtsAllocatorState_t ll_alloc_low_state;
+#endif
static ErtsAllocatorState_t temp_alloc_state;
static ErtsAllocatorState_t eheap_alloc_state;
static ErtsAllocatorState_t binary_alloc_state;
@@ -166,6 +170,10 @@ typedef struct {
struct au_init binary_alloc;
struct au_init ets_alloc;
struct au_init driver_alloc;
+#if HALFWORD_HEAP
+ struct au_init std_alloc_low;
+ struct au_init ll_alloc_low;
+#endif
} erts_alc_hndl_args_init_t;
#define ERTS_AU_INIT__ {0, 0, GOODFIT, DEFAULT_ALLCTR_INIT, {1,1,1,1}}
@@ -193,6 +201,10 @@ set_default_sl_alloc_opts(struct au_init *ip)
#endif
ip->init.util.ts = ERTS_ALC_MTA_SHORT_LIVED;
ip->init.util.rsbcst = 80;
+#if HALFWORD_HEAP
+ ip->init.util.low_mem = 1;
+#endif
+
}
static void
@@ -256,6 +268,9 @@ set_default_temp_alloc_opts(struct au_init *ip)
ip->init.util.ts = ERTS_ALC_MTA_TEMPORARY;
ip->init.util.rsbcst = 90;
ip->init.util.rmbcmt = 100;
+#if HALFWORD_HEAP
+ ip->init.util.low_mem = 1;
+#endif
}
static void
@@ -275,6 +290,9 @@ set_default_eheap_alloc_opts(struct au_init *ip)
#endif
ip->init.util.ts = ERTS_ALC_MTA_EHEAP;
ip->init.util.rsbcst = 50;
+#if HALFWORD_HEAP
+ ip->init.util.low_mem = 1;
+#endif
}
static void
@@ -531,6 +549,20 @@ erts_alloc_init(int *argc, char **argv, ErtsAllocInitOpts *eaiop)
erts_allctrs[ERTS_ALC_A_SYSTEM].free = erts_sys_free;
erts_allctrs_info[ERTS_ALC_A_SYSTEM].enabled = 1;
+#if HALFWORD_HEAP
+ /* Init low memory variants by cloning */
+ init.std_alloc_low = init.std_alloc;
+ init.std_alloc_low.init.util.alloc_no = ERTS_ALC_A_STANDARD_LOW;
+ init.std_alloc_low.init.util.low_mem = 1;
+
+ init.ll_alloc_low = init.ll_alloc;
+ init.ll_alloc_low.init.util.alloc_no = ERTS_ALC_A_LONG_LIVED_LOW;
+ init.ll_alloc_low.init.util.low_mem = 1;
+
+ set_au_allocator(ERTS_ALC_A_STANDARD_LOW, &init.std_alloc_low);
+ set_au_allocator(ERTS_ALC_A_LONG_LIVED_LOW, &init.ll_alloc_low);
+#endif /* HALFWORD */
+
set_au_allocator(ERTS_ALC_A_TEMPORARY, &init.temp_alloc);
set_au_allocator(ERTS_ALC_A_SHORT_LIVED, &init.sl_alloc);
set_au_allocator(ERTS_ALC_A_STANDARD, &init.std_alloc);
@@ -576,7 +608,14 @@ erts_alloc_init(int *argc, char **argv, ErtsAllocInitOpts *eaiop)
start_au_allocator(ERTS_ALC_A_LONG_LIVED,
&init.ll_alloc,
&ll_alloc_state);
-
+#if HALFWORD_HEAP
+ start_au_allocator(ERTS_ALC_A_LONG_LIVED_LOW,
+ &init.ll_alloc_low,
+ &ll_alloc_low_state);
+ start_au_allocator(ERTS_ALC_A_STANDARD_LOW,
+ &init.std_alloc_low,
+ &std_alloc_low_state);
+#endif
start_au_allocator(ERTS_ALC_A_EHEAP,
&init.eheap_alloc,
&eheap_alloc_state);
@@ -612,11 +651,9 @@ erts_alloc_init(int *argc, char **argv, ErtsAllocInitOpts *eaiop)
erts_set_fix_size(ERTS_ALC_T_PROC, sizeof(Process));
erts_set_fix_size(ERTS_ALC_T_DB_TABLE, sizeof(DbTable));
erts_set_fix_size(ERTS_ALC_T_ATOM, sizeof(Atom));
- erts_set_fix_size(ERTS_ALC_T_EXPORT, sizeof(Export));
+
erts_set_fix_size(ERTS_ALC_T_MODULE, sizeof(Module));
erts_set_fix_size(ERTS_ALC_T_REG_PROC, sizeof(RegProc));
- erts_set_fix_size(ERTS_ALC_T_MONITOR_SH, ERTS_MONITOR_SH_SIZE*sizeof(Uint));
- erts_set_fix_size(ERTS_ALC_T_NLINK_SH, ERTS_LINK_SH_SIZE*sizeof(Uint));
erts_set_fix_size(ERTS_ALC_T_FUN_ENTRY, sizeof(ErlFunEntry));
#ifdef ERTS_ALC_T_DRV_EV_D_STATE
erts_set_fix_size(ERTS_ALC_T_DRV_EV_D_STATE,
@@ -626,6 +663,11 @@ erts_alloc_init(int *argc, char **argv, ErtsAllocInitOpts *eaiop)
erts_set_fix_size(ERTS_ALC_T_DRV_SEL_D_STATE,
sizeof(ErtsDrvSelectDataState));
#endif
+#if !HALFWORD_HEAP
+ erts_set_fix_size(ERTS_ALC_T_EXPORT, sizeof(Export));
+ erts_set_fix_size(ERTS_ALC_T_MONITOR_SH, ERTS_MONITOR_SH_SIZE*sizeof(Uint));
+ erts_set_fix_size(ERTS_ALC_T_NLINK_SH, ERTS_LINK_SH_SIZE*sizeof(Uint));
+#endif
#endif
#endif
@@ -638,6 +680,15 @@ set_au_allocator(ErtsAlcType_t alctr_n, struct au_init *init)
ErtsAllocatorInfo_t *ai = &erts_allctrs_info[alctr_n];
ErtsAllocatorThrSpec_t *tspec = &erts_allctr_thr_spec[alctr_n];
+#if HALFWORD_HEAP
+ /* If halfword heap, silently ignore any disabling of internal
+ * allocators for low memory
+ */
+ if (init->init.util.low_mem) {
+ init->enable = 1;
+ }
+#endif
+
if (!init->enable) {
af->alloc = erts_sys_alloc;
af->realloc = erts_sys_realloc;
@@ -1348,14 +1399,6 @@ handle_args(int *argc, char **argv, erts_alc_hndl_args_init_t *init)
argv[j++] = argv[i];
}
*argc = j;
-#if HALFWORD_HEAP
- /* If halfword heap, silently ignore any disabling of internal
- allocators */
- for (i = 0; i < aui_sz; ++i)
- aui[i]->enable = 1;
-#endif
-
-
}
static char *type_no_str(ErtsAlcType_t n)
@@ -1528,10 +1571,10 @@ erts_realloc_n_enomem(ErtsAlcType_t n, void *ptr, Uint size)
erts_alc_fatal_error(ERTS_ALC_E_NOMEM, ERTS_ALC_O_REALLOC, n, size);
}
-static ERTS_INLINE Uint
+static ERTS_INLINE UWord
alcu_size(ErtsAlcType_t ai)
{
- Uint res = 0;
+ UWord res = 0;
ASSERT(erts_allctrs_info[ai].enabled);
ASSERT(erts_allctrs_info[ai].alloc_util);
@@ -1563,6 +1606,49 @@ alcu_size(ErtsAlcType_t ai)
return res;
}
+#if HALFWORD_HEAP
+static ERTS_INLINE int
+alcu_is_low(ErtsAlcType_t ai)
+{
+ int is_low = 0;
+ ASSERT(erts_allctrs_info[ai].enabled);
+ ASSERT(erts_allctrs_info[ai].alloc_util);
+
+ if (!erts_allctrs_info[ai].thr_spec) {
+ Allctr_t *allctr = erts_allctrs_info[ai].extra;
+ is_low = allctr->mseg_opt.low_mem;
+ }
+ else {
+ ErtsAllocatorThrSpec_t *tspec = &erts_allctr_thr_spec[ai];
+ int i;
+# ifdef DEBUG
+ int found_one = 0;
+# endif
+
+ ASSERT(tspec->all_thr_safe);
+ ASSERT(tspec->enabled);
+
+ for (i = tspec->size - 1; i >= 0; i--) {
+ Allctr_t *allctr = tspec->allctr[i];
+ if (allctr) {
+# ifdef DEBUG
+ if (!found_one) {
+ is_low = allctr->mseg_opt.low_mem;
+ found_one = 1;
+ }
+ else ASSERT(is_low == allctr->mseg_opt.low_mem);
+# else
+ is_low = allctr->mseg_opt.low_mem;
+ break;
+# endif
+ }
+ }
+ ASSERT(found_one);
+ }
+ return is_low;
+}
+#endif /* HALFWORD */
+
Eterm
erts_memory(int *print_to_p, void *print_to_arg, void *proc, Eterm earg)
{
@@ -1579,22 +1665,28 @@ erts_memory(int *print_to_p, void *print_to_arg, void *proc, Eterm earg)
int code;
int ets;
int maximum;
+#if HALFWORD_HEAP
+ int low;
+#endif
} want = {0};
struct {
- Uint total;
- Uint processes;
- Uint processes_used;
- Uint system;
- Uint atom;
- Uint atom_used;
- Uint binary;
- Uint code;
- Uint ets;
- Uint maximum;
+ UWord total;
+ UWord processes;
+ UWord processes_used;
+ UWord system;
+ UWord atom;
+ UWord atom_used;
+ UWord binary;
+ UWord code;
+ UWord ets;
+ UWord maximum;
+#if HALFWORD_HEAP
+ UWord low;
+#endif
} size = {0};
- Eterm atoms[sizeof(size)/sizeof(Uint)];
- Uint *uintps[sizeof(size)/sizeof(Uint)];
- Eterm euints[sizeof(size)/sizeof(Uint)];
+ Eterm atoms[sizeof(size)/sizeof(UWord)];
+ UWord *uintps[sizeof(size)/sizeof(UWord)];
+ Eterm euints[sizeof(size)/sizeof(UWord)];
int want_tot_or_sys;
int length;
Eterm res = THE_NON_VALUE;
@@ -1646,7 +1738,11 @@ erts_memory(int *print_to_p, void *print_to_arg, void *proc, Eterm earg)
atoms[length] = am_maximum;
uintps[length++] = &size.maximum;
}
-
+#if HALFWORD_HEAP
+ want.low = 1;
+ atoms[length] = am_low;
+ uintps[length++] = &size.low;
+#endif
}
else {
DeclareTmpHeapNoproc(tmp_heap,2);
@@ -1740,6 +1836,15 @@ erts_memory(int *print_to_p, void *print_to_arg, void *proc, Eterm earg)
return am_badarg;
}
break;
+#if HALFWORD_HEAP
+ case am_low:
+ if (!want.low) {
+ want.low = 1;
+ atoms[length] = am_low;
+ uintps[length++] = &size.low;
+ }
+ break;
+#endif
default:
UnUseTmpHeapNoproc(2);
return am_badarg;
@@ -1769,7 +1874,7 @@ erts_memory(int *print_to_p, void *print_to_arg, void *proc, Eterm earg)
ASSERT(length <= sizeof(atoms)/sizeof(Eterm));
ASSERT(length <= sizeof(euints)/sizeof(Eterm));
- ASSERT(length <= sizeof(uintps)/sizeof(Uint));
+ ASSERT(length <= sizeof(uintps)/sizeof(UWord));
if (proc) {
@@ -1788,8 +1893,8 @@ erts_memory(int *print_to_p, void *print_to_arg, void *proc, Eterm earg)
for (ai = ERTS_ALC_A_MIN; ai <= ERTS_ALC_A_MAX; ai++) {
if (erts_allctrs_info[ai].alloc_util) {
- Uint *save;
- Uint asz;
+ UWord *save;
+ UWord asz;
switch (ai) {
case ERTS_ALC_A_TEMPORARY:
/*
@@ -1814,6 +1919,11 @@ erts_memory(int *print_to_p, void *print_to_arg, void *proc, Eterm earg)
if (save)
*save = asz;
size.total += asz;
+#if HALFWORD_HEAP
+ if (alcu_is_low(ai)) {
+ size.low += asz;
+ }
+#endif
}
}
}
@@ -1821,7 +1931,7 @@ erts_memory(int *print_to_p, void *print_to_arg, void *proc, Eterm earg)
if (want_tot_or_sys || want.processes || want.processes_used) {
- Uint tmp;
+ UWord tmp;
if (ERTS_MEM_NEED_ALL_ALCU)
tmp = size.processes;
@@ -1836,6 +1946,9 @@ erts_memory(int *print_to_p, void *print_to_arg, void *proc, Eterm earg)
size.processes = size.processes_used = tmp;
+#if HALFWORD_HEAP
+ /* BUG: We ignore link and monitor memory */
+#else
erts_fix_info(ERTS_ALC_T_NLINK_SH, &efi);
size.processes += efi.total;
size.processes_used += efi.used;
@@ -1843,6 +1956,7 @@ erts_memory(int *print_to_p, void *print_to_arg, void *proc, Eterm earg)
erts_fix_info(ERTS_ALC_T_MONITOR_SH, &efi);
size.processes += efi.total;
size.processes_used += efi.used;
+#endif
erts_fix_info(ERTS_ALC_T_PROC, &efi);
size.processes += efi.total;
@@ -1879,8 +1993,12 @@ erts_memory(int *print_to_p, void *print_to_arg, void *proc, Eterm earg)
erts_fix_info(ERTS_ALC_T_MODULE, &efi);
size.code += efi.used;
size.code += export_table_sz();
+#if HALFWORD_HEAP
+ size.code += export_list_size() * sizeof(Export);
+#else
erts_fix_info(ERTS_ALC_T_EXPORT, &efi);
size.code += efi.used;
+#endif
size.code += erts_fun_table_sz();
erts_fix_info(ERTS_ALC_T_FUN_ENTRY, &efi);
size.code += efi.used;
@@ -1913,7 +2031,7 @@ erts_memory(int *print_to_p, void *print_to_arg, void *proc, Eterm earg)
/* Print result... */
erts_print(to, arg, "=memory\n");
for (i = 0; i < length; i++)
- erts_print(to, arg, "%T: %beu\n", atoms[i], *uintps[i]);
+ erts_print(to, arg, "%T: %bpu\n", atoms[i], *uintps[i]);
}
if (proc) {
@@ -1926,9 +2044,9 @@ erts_memory(int *print_to_p, void *print_to_arg, void *proc, Eterm earg)
if (only_one_value) {
ASSERT(length == 1);
hsz = 0;
- erts_bld_uint(NULL, &hsz, *uintps[0]);
+ erts_bld_uword(NULL, &hsz, *uintps[0]);
hp = hsz ? HAlloc((Process *) proc, hsz) : NULL;
- res = erts_bld_uint(&hp, NULL, *uintps[0]);
+ res = erts_bld_uword(&hp, NULL, *uintps[0]);
}
else {
Uint **hpp = NULL;
@@ -1938,7 +2056,7 @@ erts_memory(int *print_to_p, void *print_to_arg, void *proc, Eterm earg)
while (1) {
int i;
for (i = 0; i < length; i++)
- euints[i] = erts_bld_uint(hpp, hszp, *uintps[i]);
+ euints[i] = erts_bld_uword(hpp, hszp, *uintps[i]);
res = erts_bld_2tup_list(hpp, hszp, length, atoms, euints);
if (hpp)
break;
diff --git a/erts/emulator/beam/erl_alloc.types b/erts/emulator/beam/erl_alloc.types
index ca71798917..c6cc0e1fac 100644
--- a/erts/emulator/beam/erl_alloc.types
+++ b/erts/emulator/beam/erl_alloc.types
@@ -75,6 +75,11 @@ allocator EHEAP true eheap_alloc
allocator ETS true ets_alloc
allocator FIXED_SIZE true fix_alloc
++if halfword
+allocator LONG_LIVED_LOW true ll_alloc_low
+allocator STANDARD_LOW true std_alloc_low
++endif
+
+else # Non smp build
allocator TEMPORARY false temp_alloc
@@ -85,12 +90,18 @@ allocator EHEAP false eheap_alloc
allocator ETS false ets_alloc
allocator FIXED_SIZE false fix_alloc
++if halfword
+allocator LONG_LIVED_LOW false ll_alloc_low
+allocator STANDARD_LOW false std_alloc_low
++endif
+
+endif
allocator BINARY true binary_alloc
allocator DRIVER true driver_alloc
+
# --- Class declarations -----------------------------------------------------
#
# Syntax: class <CLASS> <DESCRIPTION>
@@ -125,14 +136,9 @@ class SYSTEM system_data
type PROC FIXED_SIZE PROCESSES proc
type ATOM FIXED_SIZE ATOM atom_entry
-type EXPORT FIXED_SIZE CODE export_entry
type MODULE FIXED_SIZE CODE module_entry
type REG_PROC FIXED_SIZE PROCESSES reg_proc
type LINK_LH STANDARD PROCESSES link_lh
-type MONITOR_SH FIXED_SIZE PROCESSES monitor_sh
-type MONITOR_LH STANDARD PROCESSES monitor_lh
-type NLINK_SH FIXED_SIZE PROCESSES nlink_sh
-type NLINK_LH STANDARD PROCESSES nlink_lh
type SUSPEND_MON STANDARD PROCESSES suspend_monitor
type PEND_SUSPEND SHORT_LIVED PROCESSES pending_suspend
type PROC_LIST SHORT_LIVED PROCESSES proc_list
@@ -175,7 +181,6 @@ type DRIVER STANDARD SYSTEM driver
type NIF DRIVER SYSTEM nif_internal
type BINARY BINARY BINARIES binary
type NBIF_TABLE SYSTEM SYSTEM nbif_tab
-type CODE LONG_LIVED CODE code
type ARG_REG STANDARD PROCESSES arg_reg
type PROC_DICT STANDARD PROCESSES proc_dict
type CALLS_BUF STANDARD PROCESSES calls_buf
@@ -193,10 +198,8 @@ type DB_FIXATION SHORT_LIVED ETS db_fixation
type DB_FIX_DEL SHORT_LIVED ETS fixed_del
type DB_TABLES LONG_LIVED ETS db_tabs
type DB_NTAB_ENT STANDARD ETS db_named_table_entry
-type DB_HEIR_DATA STANDARD ETS db_heir_data
type DB_TMP TEMPORARY ETS db_tmp
type DB_MC_STK TEMPORARY ETS db_mc_stack
-type DB_MS_PSDO_PROC LONG_LIVED ETS db_match_pseudo_proc
type DB_MS_RUN_HEAP SHORT_LIVED ETS db_match_spec_run_heap
type DB_MS_CMPL_HEAP TEMPORARY ETS db_match_spec_cmpl_heap
type DB_SEG ETS ETS db_segment
@@ -213,10 +216,8 @@ type LOGGER_DSBUF TEMPORARY SYSTEM logger_dsbuf
type TMP_DSBUF TEMPORARY SYSTEM tmp_dsbuf
type INFO_DSBUF SYSTEM SYSTEM info_dsbuf
# INFO_DSBUF have to use the SYSTEM allocator; otherwise, a deadlock might occur
-type SCHDLR_DATA LONG_LIVED SYSTEM scheduler_data
type SCHDLR_SLP_INFO LONG_LIVED SYSTEM scheduler_sleep_info
type RUNQS LONG_LIVED SYSTEM run_queues
-type DDLL_PROCESS STANDARD SYSTEM ddll_processes
type DDLL_HANDLE STANDARD SYSTEM ddll_handle
type DDLL_ERRCODES LONG_LIVED SYSTEM ddll_errcodes
type DDLL_TMP_BUF TEMPORARY SYSTEM ddll_tmp_buf
@@ -327,13 +328,45 @@ type SSB SHORT_LIVED PROCESSES ssb
+endif
++if halfword
+
+type DDLL_PROCESS STANDARD_LOW SYSTEM ddll_processes
+type MONITOR_LH STANDARD_LOW PROCESSES monitor_lh
+type NLINK_LH STANDARD_LOW PROCESSES nlink_lh
+type CODE LONG_LIVED_LOW CODE code
+type DB_HEIR_DATA STANDARD_LOW ETS db_heir_data
+type DB_MS_PSDO_PROC LONG_LIVED_LOW ETS db_match_pseudo_proc
+type SCHDLR_DATA LONG_LIVED_LOW SYSTEM scheduler_data
+type LL_TEMP_TERM LONG_LIVED_LOW SYSTEM ll_temp_term
+
+# no FIXED_SIZE for low memory
+type EXPORT STANDARD_LOW CODE export_entry
+type MONITOR_SH STANDARD_LOW PROCESSES monitor_sh
+type NLINK_SH STANDARD_LOW PROCESSES nlink_sh
+
++else # "fullword"
+
+type DDLL_PROCESS STANDARD SYSTEM ddll_processes
+type MONITOR_LH STANDARD PROCESSES monitor_lh
+type NLINK_LH STANDARD PROCESSES nlink_lh
+type CODE LONG_LIVED CODE code
+type DB_HEIR_DATA STANDARD ETS db_heir_data
+type DB_MS_PSDO_PROC LONG_LIVED ETS db_match_pseudo_proc
+type SCHDLR_DATA LONG_LIVED SYSTEM scheduler_data
+type LL_TEMP_TERM LONG_LIVED SYSTEM ll_temp_term
+
+type EXPORT FIXED_SIZE CODE export_entry
+type MONITOR_SH FIXED_SIZE PROCESSES monitor_sh
+type NLINK_SH FIXED_SIZE PROCESSES nlink_sh
+
++endif
+
+
#
# Types used by system specific code
#
type TEMP_TERM TEMPORARY SYSTEM temp_term
-type LL_TEMP_TERM LONG_LIVED SYSTEM ll_temp_term
-
type DRV_TAB LONG_LIVED SYSTEM drv_tab
type DRV_EV_STATE LONG_LIVED SYSTEM driver_event_state
type DRV_EV_D_STATE FIXED_SIZE SYSTEM driver_event_data_state
diff --git a/erts/emulator/beam/erl_alloc_util.c b/erts/emulator/beam/erl_alloc_util.c
index 84c72439a3..cc04ef65bf 100644
--- a/erts/emulator/beam/erl_alloc_util.c
+++ b/erts/emulator/beam/erl_alloc_util.c
@@ -1639,6 +1639,9 @@ static struct {
Eterm e;
Eterm t;
Eterm ramv;
+#if HALFWORD_HEAP
+ Eterm low;
+#endif
Eterm sbct;
#if HAVE_ERTS_MSEG
Eterm asbcst;
@@ -1724,6 +1727,9 @@ init_atoms(Allctr_t *allctr)
AM_INIT(e);
AM_INIT(t);
AM_INIT(ramv);
+#if HALFWORD_HEAP
+ AM_INIT(low);
+#endif
AM_INIT(sbct);
#if HAVE_ERTS_MSEG
AM_INIT(asbcst);
@@ -2168,6 +2174,9 @@ info_options(Allctr_t *allctr,
"option e: true\n"
"option t: %s\n"
"option ramv: %s\n"
+#if HALFWORD_HEAP
+ "option low: %s\n"
+#endif
"option sbct: %beu\n"
#if HAVE_ERTS_MSEG
"option asbcst: %bpu\n"
@@ -2185,6 +2194,9 @@ info_options(Allctr_t *allctr,
"option mbcgs: %beu\n",
topt,
allctr->ramv ? "true" : "false",
+#if HALFWORD_HEAP
+ allctr->mseg_opt.low_mem ? "true" : "false",
+#endif
allctr->sbc_threshold,
#if HAVE_ERTS_MSEG
allctr->mseg_opt.abs_shrink_th,
@@ -2243,6 +2255,9 @@ info_options(Allctr_t *allctr,
add_2tup(hpp, szp, &res,
am.sbct,
bld_uint(hpp, szp, allctr->sbc_threshold));
+#if HALFWORD_HEAP
+ add_2tup(hpp, szp, &res, am.low, allctr->mseg_opt.low_mem ? am_true : am_false);
+#endif
add_2tup(hpp, szp, &res, am.ramv, allctr->ramv ? am_true : am_false);
add_2tup(hpp, szp, &res, am.t, (allctr->t
? bld_uint(hpp, szp, (Uint) allctr->t)
@@ -3105,13 +3120,12 @@ erts_alcu_start(Allctr_t *allctr, AllctrInit_t *init)
goto error;
#if HAVE_ERTS_MSEG
- {
- ErtsMsegOpt_t mseg_opt = ERTS_MSEG_DEFAULT_OPT_INITIALIZER;
-
- sys_memcpy((void *) &allctr->mseg_opt,
- (void *) &mseg_opt,
- sizeof(ErtsMsegOpt_t));
- }
+ sys_memcpy((void *) &allctr->mseg_opt,
+ (void *) &erts_mseg_default_opt,
+ sizeof(ErtsMsegOpt_t));
+# if HALFWORD_HEAP
+ allctr->mseg_opt.low_mem = init->low_mem;
+# endif
#endif
allctr->name_prefix = init->name_prefix;
diff --git a/erts/emulator/beam/erl_alloc_util.h b/erts/emulator/beam/erl_alloc_util.h
index d296081714..ddf84c086c 100644
--- a/erts/emulator/beam/erl_alloc_util.h
+++ b/erts/emulator/beam/erl_alloc_util.h
@@ -38,6 +38,7 @@ typedef struct {
int tspec;
int tpref;
int ramv;
+ int low_mem; /* HALFWORD only */
UWord sbct;
UWord asbcst;
UWord rsbcst;
@@ -70,6 +71,7 @@ typedef struct {
0, /* (bool) tspec: thread specific */\
0, /* (bool) tpref: thread preferred */\
0, /* (bool) ramv: realloc always moves */\
+ 0, /* (bool) low_mem: HALFWORD only */\
512*1024, /* (bytes) sbct: sbc threshold */\
2*1024*2024, /* (amount) asbcst: abs sbc shrink threshold */\
20, /* (%) rsbcst: rel sbc shrink threshold */\
@@ -97,6 +99,7 @@ typedef struct {
0, /* (bool) tspec: thread specific */\
0, /* (bool) tpref: thread preferred */\
0, /* (bool) ramv: realloc always moves */\
+ 0, /* (bool) low_mem: HALFWORD only */\
64*1024, /* (bytes) sbct: sbc threshold */\
2*1024*2024, /* (amount) asbcst: abs sbc shrink threshold */\
20, /* (%) rsbcst: rel sbc shrink threshold */\
diff --git a/erts/emulator/beam/erl_db_hash.c b/erts/emulator/beam/erl_db_hash.c
index 9ef990cc4f..694348e31d 100644
--- a/erts/emulator/beam/erl_db_hash.c
+++ b/erts/emulator/beam/erl_db_hash.c
@@ -2085,7 +2085,14 @@ static void db_print_hash(int to, void *to_arg, int show, DbTable *tbl)
while(list != 0) {
if (list->hvalue == INVALID_HASH)
erts_print(to, to_arg, "*");
- erts_print(to, to_arg, "%T", make_tuple(list->dbterm.tpl));
+ if (tb->common.compress) {
+ Eterm key = GETKEY(tb, list->dbterm.tpl);
+ erts_print(to, to_arg, "key=%R", key, list->dbterm.tpl);
+ }
+ else {
+ Eterm obj = make_tuple_rel(list->dbterm.tpl,list->dbterm.tpl);
+ erts_print(to, to_arg, "%R", obj, list->dbterm.tpl);
+ }
if (list->next != 0)
erts_print(to, to_arg, ",");
list = list->next;
diff --git a/erts/emulator/beam/erl_db_tree.c b/erts/emulator/beam/erl_db_tree.c
index a59c0c258d..eb77d1281a 100644
--- a/erts/emulator/beam/erl_db_tree.c
+++ b/erts/emulator/beam/erl_db_tree.c
@@ -179,7 +179,7 @@ static ERTS_INLINE TreeDbTerm* replace_dbterm(DbTableTree *tb, TreeDbTerm* old,
static TreeDbTerm *traverse_until(TreeDbTerm *t, int *current, int to);
static void check_slot_pos(DbTableTree *tb);
static void check_saved_stack(DbTableTree *tb);
-static int check_table_tree(TreeDbTerm *t);
+static int check_table_tree(DbTableTree* tb, TreeDbTerm *t);
#define TREE_DEBUG
#endif
@@ -194,8 +194,8 @@ static int check_table_tree(TreeDbTerm *t);
** Debugging dump
*/
-static void do_dump_tree2(int to, void *to_arg, int show, TreeDbTerm *t,
- int offset);
+static void do_dump_tree2(DbTableTree*, int to, void *to_arg, int show,
+ TreeDbTerm *t, int offset);
#else
@@ -1730,6 +1730,7 @@ static int db_select_delete_tree(Process *p, DbTable *tbl,
** Other interface routines (not directly coupled to one bif)
*/
+
/* Display tree contents (for dump) */
static void db_print_tree(int to, void *to_arg,
int show,
@@ -1740,7 +1741,7 @@ static void db_print_tree(int to, void *to_arg,
if (show)
erts_print(to, to_arg, "\nTree data dump:\n"
"------------------------------------------------\n");
- do_dump_tree2(to, to_arg, show, tb->root, 0);
+ do_dump_tree2(&tbl->tree, to, to_arg, show, tb->root, 0);
if (show)
erts_print(to, to_arg, "\n"
"------------------------------------------------\n");
@@ -2694,7 +2695,7 @@ static Sint do_cmp_partly_bound(Eterm a, Eterm b, Eterm* b_base, int *done)
while (1) {
if ((j = do_cmp_partly_bound(*aa++, *bb++, b_base, done)) != 0 || *done)
return j;
- if (*aa==*bb)
+ if (is_same(*aa, NULL, *bb, b_base))
return 0;
if (is_not_list(*aa) || is_not_list(*bb))
return do_cmp_partly_bound(*aa, *bb, b_base, done);
@@ -2742,7 +2743,7 @@ static Sint cmp_partly_bound(Eterm partly_bound_key, Eterm bound_key, Eterm* bk_
erts_fprintf(stderr," > ");
else
erts_fprintf(stderr," == ");
- erts_fprintf(stderr,"%T\n",bound_key); // HALFWORD BUG: printing rterm
+ erts_fprintf(stderr,"%R\n", bound_key, bk_base);
#endif
return ret;
}
@@ -3084,19 +3085,28 @@ static int doit_select_delete(DbTableTree *tb, TreeDbTerm *this, void *ptr,
}
#ifdef TREE_DEBUG
-static void do_dump_tree2(int to, void *to_arg, int show, TreeDbTerm *t,
- int offset)
+static void do_dump_tree2(DbTableTree* tb, int to, void *to_arg, int show,
+ TreeDbTerm *t, int offset)
{
if (t == NULL)
- return 0;
- do_dump_tree2(to, to_arg, show, t->right, offset + 4);
+ return;
+ do_dump_tree2(tb, to, to_arg, show, t->right, offset + 4);
if (show) {
- erts_print(to, to_arg, "%*s%T (addr = %p, bal = %d)\n"
- offset, "", make_tuple(t->dbterm.tpl),
+ const char* prefix;
+ Eterm term;
+ if (tb->common.compress) {
+ prefix = "key=";
+ term = GETKEY(tb, t->dbterm.tpl);
+ }
+ else {
+ prefix = "";
+ term = make_tuple_rel(t->dbterm.tpl,t->dbterm.tpl);
+ }
+ erts_print(to, to_arg, "%*s%s%R (addr = %p, bal = %d)\n",
+ offset, "", prefix, term, t->dbterm.tpl,
t, t->balance);
}
- do_dump_tree2(to, to_arg, show, t->left, offset + 4);
- return sum;
+ do_dump_tree2(tb, to, to_arg, show, t->left, offset + 4);
}
#endif
@@ -3106,7 +3116,7 @@ static void do_dump_tree2(int to, void *to_arg, int show, TreeDbTerm *t,
void db_check_table_tree(DbTable *tbl)
{
DbTableTree *tb = &tbl->tree;
- check_table_tree(tb->root);
+ check_table_tree(tb, tb->root);
check_saved_stack(tb);
check_slot_pos(tb);
}
@@ -3137,7 +3147,7 @@ static void check_slot_pos(DbTableTree *tb)
"element position %d is really 0x%08X, when stack says "
"it's 0x%08X\n", tb->stack.slot, t,
tb->stack.array[tb->stack.pos - 1]);
- do_dump_tree2(ERTS_PRINT_STDERR, NULL, 1, tb->root, 0);
+ do_dump_tree2(tb, ERTS_PRINT_STDERR, NULL, 1, tb->root, 0);
}
}
@@ -3152,14 +3162,14 @@ static void check_saved_stack(DbTableTree *tb)
if (t != stack->array[0]) {
erts_fprintf(stderr,"tb->stack[0] is 0x%08X, should be 0x%08X\n",
stack->array[0], t);
- do_dump_tree2(ERTS_PRINT_STDERR, NULL, 1, tb->root, 0);
+ do_dump_tree2(tb, ERTS_PRINT_STDERR, NULL, 1, tb->root, 0);
return;
}
while (n < stack->pos) {
if (t == NULL) {
erts_fprintf(stderr, "NULL pointer in tree when stack not empty,"
" stack depth is %d\n", n);
- do_dump_tree2(ERTS_PRINT_STDERR, NULL, 1, tb->root, 0);
+ do_dump_tree2(tb, ERTS_PRINT_STDERR, NULL, 1, tb->root, 0);
return;
}
n++;
@@ -3173,28 +3183,26 @@ static void check_saved_stack(DbTableTree *tb)
"represent child pointer in tree!"
"(left == 0x%08X, right == 0x%08X\n",
n, tb->stack[n], t->left, t->right);
- do_dump_tree2(ERTS_PRINT_STDERR, NULL, 1, tb->root, 0);
+ do_dump_tree2(tb, ERTS_PRINT_STDERR, NULL, 1, tb->root, 0);
return;
}
}
}
}
-static int check_table_tree(TreeDbTerm *t)
+static int check_table_tree(DbTableTree* tb, TreeDbTerm *t)
{
int lh, rh;
if (t == NULL)
return 0;
- lh = check_table_tree(t->left);
- rh = check_table_tree(t->right);
+ lh = check_table_tree(tb, t->left);
+ rh = check_table_tree(tb, t->right);
if ((rh - lh) != t->balance) {
erts_fprintf(stderr, "Invalid tree balance for this node:\n");
- erts_fprintf(stderr,"balance = %d, left = 0x%08X, right = 0x%08X\n"
- "data = %T",
- t->balance, t->left, t->right,
- make_tuple(t->dbterm.tpl));
+ erts_fprintf(stderr,"balance = %d, left = 0x%08X, right = 0x%08X\n",
+ t->balance, t->left, t->right);
erts_fprintf(stderr,"\nDump:\n---------------------------------\n");
- do_dump_tree2(ERTS_PRINT_STDERR, NULL, 1, t, 0);
+ do_dump_tree2(tb, ERTS_PRINT_STDERR, NULL, 1, t, 0);
erts_fprintf(stderr,"\n---------------------------------\n");
}
return ((rh > lh) ? rh : lh) + 1;
diff --git a/erts/emulator/beam/erl_lock_check.c b/erts/emulator/beam/erl_lock_check.c
index 9e18997890..9180508a49 100644
--- a/erts/emulator/beam/erl_lock_check.c
+++ b/erts/emulator/beam/erl_lock_check.c
@@ -240,7 +240,7 @@ typedef struct erts_lc_locked_lock_t_ erts_lc_locked_lock_t;
struct erts_lc_locked_lock_t_ {
erts_lc_locked_lock_t *next;
erts_lc_locked_lock_t *prev;
- Eterm extra;
+ UWord extra;
Sint16 id;
Uint16 flags;
};
@@ -441,12 +441,12 @@ new_locked_lock(erts_lc_lock_t *lck, Uint16 op_flags)
}
static void
-print_lock2(char *prefix, Sint16 id, Eterm extra, Uint16 flags, char *suffix)
+print_lock2(char *prefix, Sint16 id, Wterm extra, Uint16 flags, char *suffix)
{
char *lname = (0 <= id && id < ERTS_LOCK_ORDER_SIZE
? erts_lock_order[id].name
: "unknown");
- if (is_boxed(extra))
+ if (is_not_immed(extra))
erts_fprintf(stderr,
"%s'%s:%p%s'%s%s",
prefix,
@@ -1260,7 +1260,8 @@ erts_lc_init_lock(erts_lc_lock_t *lck, char *name, Uint16 flags)
{
lck->id = erts_lc_get_lock_order_id(name);
- lck->extra = make_boxed(&lck->extra);
+ lck->extra = &lck->extra;
+ ASSERT(is_not_immed(lck->extra));
lck->flags = flags;
lck->inited = ERTS_LC_INITITALIZED;
}
@@ -1270,6 +1271,7 @@ erts_lc_init_lock_x(erts_lc_lock_t *lck, char *name, Uint16 flags, Eterm extra)
{
lck->id = erts_lc_get_lock_order_id(name);
lck->extra = extra;
+ ASSERT(is_immed(lck->extra));
lck->flags = flags;
lck->inited = ERTS_LC_INITITALIZED;
}
diff --git a/erts/emulator/beam/erl_lock_check.h b/erts/emulator/beam/erl_lock_check.h
index cdb06d4458..b67f36fa06 100644
--- a/erts/emulator/beam/erl_lock_check.h
+++ b/erts/emulator/beam/erl_lock_check.h
@@ -39,7 +39,7 @@ typedef struct {
int inited;
Sint16 id;
Uint16 flags;
- Eterm extra;
+ UWord extra;
} erts_lc_lock_t;
#define ERTS_LC_INITITALIZED 0x7f7f7f7f
diff --git a/erts/emulator/beam/erl_printf_term.c b/erts/emulator/beam/erl_printf_term.c
index b71404fd27..34da9cab84 100644
--- a/erts/emulator/beam/erl_printf_term.c
+++ b/erts/emulator/beam/erl_printf_term.c
@@ -114,13 +114,13 @@ do { \
/* return 0 if list is not a non-empty flat list of printable characters */
static int
-is_printable_string(Eterm list)
+is_printable_string(Eterm list, Eterm* base)
{
int len = 0;
int c;
while(is_list(list)) {
- Eterm* consp = list_val(list);
+ Eterm* consp = list_val_rel(list, base);
Eterm hd = CAR(consp);
if (!is_byte(hd))
@@ -226,17 +226,20 @@ static int print_atom_name(fmtfn_t fn, void* arg, Eterm atom, long *dcount)
#define PRT_LAST_ARRAY_ELEMENT ((Eterm) 7) /* Note! Must be last... */
static int
-print_term(fmtfn_t fn, void* arg, Eterm obj, long *dcount)
+print_term(fmtfn_t fn, void* arg, Eterm obj, long *dcount,
+ Eterm* obj_base) /* ignored if !HALFWORD_HEAP */
{
DECLARE_WSTACK(s);
int res;
int i;
Eterm val;
Uint32 *ref_num;
+ union {
+ UWord word;
+ Eterm* ptr;
+ }popped;
Eterm* nobj;
-#if HALFWORD_HEAP
- UWord wobj;
-#endif
+ Wterm wobj;
res = 0;
@@ -258,18 +261,17 @@ print_term(fmtfn_t fn, void* arg, Eterm obj, long *dcount)
PRINT_CHAR(res, fn, arg, '}');
goto L_outer_loop;
default:
-#if HALFWORD_HEAP
- obj = (Eterm) (wobj = WSTACK_POP(s));
-#else
- obj = WSTACK_POP(s);
-#endif
+ popped.word = WSTACK_POP(s);
+
switch (val) {
case PRT_TERM:
+ obj = (Eterm) popped.word;
break;
case PRT_ONE_CONS:
+ obj = (Eterm) popped.word;
L_print_one_cons:
{
- Eterm* cons = list_val(obj);
+ Eterm* cons = list_val_rel(obj, obj_base);
Eterm tl;
obj = CAR(cons);
@@ -288,27 +290,13 @@ print_term(fmtfn_t fn, void* arg, Eterm obj, long *dcount)
}
break;
case PRT_LAST_ARRAY_ELEMENT:
- {
-#if HALFWORD_HEAP
- Eterm* ptr = (Eterm *) wobj;
-#else
- Eterm* ptr = (Eterm *) obj;
-#endif
- obj = *ptr;
- }
+ obj = *popped.ptr;
break;
default: /* PRT_LAST_ARRAY_ELEMENT+1 and upwards */
- {
-#if HALFWORD_HEAP
- Eterm* ptr = (Eterm *) wobj;
-#else
- Eterm* ptr = (Eterm *) obj;
-#endif
- obj = *ptr++;
- WSTACK_PUSH(s, (UWord) ptr);
- WSTACK_PUSH(s, val-1);
- WSTACK_PUSH(s, PRT_COMMA);
- }
+ obj = *popped.ptr;
+ WSTACK_PUSH(s, (UWord) (popped.ptr + 1));
+ WSTACK_PUSH(s, val-1);
+ WSTACK_PUSH(s, PRT_COMMA);
break;
}
break;
@@ -325,8 +313,12 @@ print_term(fmtfn_t fn, void* arg, Eterm obj, long *dcount)
PRINT_CHAR(res, fn, arg, '>');
goto L_done;
}
-
- switch (tag_val_def(obj)) {
+#if HALFWORD_HEAP
+ wobj = is_immed(obj) ? (Wterm)obj : rterm2wterm(obj, obj_base);
+#else
+ wobj = (Wterm)obj;
+#endif
+ switch (tag_val_def(wobj)) {
case NIL_DEF:
PRINT_STRING(res, fn, arg, "[]");
break;
@@ -348,13 +340,13 @@ print_term(fmtfn_t fn, void* arg, Eterm obj, long *dcount)
int print_res;
char def_buf[64];
char *buf, *big_str;
- Uint sz = (Uint) big_decimal_estimate(obj);
+ Uint sz = (Uint) big_decimal_estimate(wobj);
sz++;
if (sz <= 64)
buf = &def_buf[0];
else
buf = erts_alloc(ERTS_ALC_T_TMP, sz);
- big_str = erts_big_to_string(obj, buf, sz);
+ big_str = erts_big_to_string(wobj, buf, sz);
print_res = erts_printf_string(fn, arg, big_str);
if (buf != &def_buf[0])
erts_free(ERTS_ALC_T_TMP, (void *) buf);
@@ -369,9 +361,9 @@ print_term(fmtfn_t fn, void* arg, Eterm obj, long *dcount)
case EXTERNAL_REF_DEF:
PRINT_STRING(res, fn, arg, "#Ref<");
PRINT_ULONG(res, fn, arg, 'u', 0, 1,
- (unsigned long) ref_channel_no(obj));
- ref_num = ref_numbers(obj);
- for (i = ref_no_of_numbers(obj)-1; i >= 0; i--) {
+ (unsigned long) ref_channel_no(wobj));
+ ref_num = ref_numbers(wobj);
+ for (i = ref_no_of_numbers(wobj)-1; i >= 0; i--) {
PRINT_CHAR(res, fn, arg, '.');
PRINT_ULONG(res, fn, arg, 'u', 0, 1, (unsigned long) ref_num[i]);
}
@@ -381,30 +373,30 @@ print_term(fmtfn_t fn, void* arg, Eterm obj, long *dcount)
case EXTERNAL_PID_DEF:
PRINT_CHAR(res, fn, arg, '<');
PRINT_ULONG(res, fn, arg, 'u', 0, 1,
- (unsigned long) pid_channel_no(obj));
+ (unsigned long) pid_channel_no(wobj));
PRINT_CHAR(res, fn, arg, '.');
PRINT_ULONG(res, fn, arg, 'u', 0, 1,
- (unsigned long) pid_number(obj));
+ (unsigned long) pid_number(wobj));
PRINT_CHAR(res, fn, arg, '.');
PRINT_ULONG(res, fn, arg, 'u', 0, 1,
- (unsigned long) pid_serial(obj));
+ (unsigned long) pid_serial(wobj));
PRINT_CHAR(res, fn, arg, '>');
break;
case PORT_DEF:
case EXTERNAL_PORT_DEF:
PRINT_STRING(res, fn, arg, "#Port<");
PRINT_ULONG(res, fn, arg, 'u', 0, 1,
- (unsigned long) port_channel_no(obj));
+ (unsigned long) port_channel_no(wobj));
PRINT_CHAR(res, fn, arg, '.');
PRINT_ULONG(res, fn, arg, 'u', 0, 1,
- (unsigned long) port_number(obj));
+ (unsigned long) port_number(wobj));
PRINT_CHAR(res, fn, arg, '>');
break;
case LIST_DEF:
- if (is_printable_string(obj)) {
+ if (is_printable_string(obj, obj_base)) {
int c;
PRINT_CHAR(res, fn, arg, '"');
- nobj = list_val(obj);
+ nobj = list_val_rel(obj, obj_base);
while (1) {
if ((*dcount)-- <= 0)
goto L_done;
@@ -418,7 +410,7 @@ print_term(fmtfn_t fn, void* arg, Eterm obj, long *dcount)
}
if (is_not_list(*nobj))
break;
- nobj = list_val(*nobj);
+ nobj = list_val_rel(*nobj, obj_base);
}
PRINT_CHAR(res, fn, arg, '"');
} else {
@@ -428,7 +420,7 @@ print_term(fmtfn_t fn, void* arg, Eterm obj, long *dcount)
}
break;
case TUPLE_DEF:
- nobj = tuple_val(obj); /* pointer to arity */
+ nobj = tuple_val(wobj); /* pointer to arity */
i = arityval(*nobj); /* arity */
PRINT_CHAR(res, fn, arg, '{');
WSTACK_PUSH(s,PRT_CLOSE_TUPLE);
@@ -440,13 +432,13 @@ print_term(fmtfn_t fn, void* arg, Eterm obj, long *dcount)
break;
case FLOAT_DEF: {
FloatDef ff;
- GET_DOUBLE(obj, ff);
+ GET_DOUBLE(wobj, ff);
PRINT_DOUBLE(res, fn, arg, 'e', 6, 0, ff.fd);
}
break;
case BINARY_DEF:
{
- ProcBin* pb = (ProcBin *) binary_val(obj);
+ ProcBin* pb = (ProcBin *) binary_val(wobj);
if (pb->size == 1)
PRINT_STRING(res, fn, arg, "<<1 byte>>");
else {
@@ -458,7 +450,7 @@ print_term(fmtfn_t fn, void* arg, Eterm obj, long *dcount)
break;
case EXPORT_DEF:
{
- Export* ep = *((Export **) (export_val(obj) + 1));
+ Export* ep = *((Export **) (export_val(wobj) + 1));
Atom* module = atom_tab(atom_val(ep->code[0]));
Atom* name = atom_tab(atom_val(ep->code[1]));
@@ -474,7 +466,7 @@ print_term(fmtfn_t fn, void* arg, Eterm obj, long *dcount)
break;
case FUN_DEF:
{
- ErlFunThing *funp = (ErlFunThing *) fun_val(obj);
+ ErlFunThing *funp = (ErlFunThing *) fun_val(wobj);
Atom *ap = atom_tab(atom_val(funp->fe->module));
PRINT_STRING(res, fn, arg, "#Fun<");
@@ -490,7 +482,7 @@ print_term(fmtfn_t fn, void* arg, Eterm obj, long *dcount)
break;
default:
PRINT_STRING(res, fn, arg, "<unknown:");
- PRINT_POINTER(res, fn, arg, (UWord) obj);
+ PRINT_POINTER(res, fn, arg, wobj);
PRINT_CHAR(res, fn, arg, '>');
break;
}
@@ -503,9 +495,10 @@ print_term(fmtfn_t fn, void* arg, Eterm obj, long *dcount)
}
int
-erts_printf_term(fmtfn_t fn, void* arg, unsigned long term, long precision)
+erts_printf_term(fmtfn_t fn, void* arg, unsigned long term, long precision,
+ unsigned long* term_base)
{
- int res = print_term(fn, arg, (Uint) term, &precision);
+ int res = print_term(fn, arg, (Eterm)term, &precision, (Eterm*)term_base);
if (res < 0)
return res;
if (precision <= 0)
diff --git a/erts/emulator/beam/erl_printf_term.h b/erts/emulator/beam/erl_printf_term.h
index 4f76028396..4ba22f12de 100644
--- a/erts/emulator/beam/erl_printf_term.h
+++ b/erts/emulator/beam/erl_printf_term.h
@@ -21,6 +21,6 @@
#define ERL_PRINTF_TERM_H__
#include "erl_printf_format.h"
-int erts_printf_term(fmtfn_t fn, void* arg, unsigned long term, long precision);
-
+int erts_printf_term(fmtfn_t fn, void* arg, unsigned long term, long precision,
+ unsigned long* term_base);
#endif
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c
index 31f23d3978..8a56976905 100644
--- a/erts/emulator/beam/erl_process.c
+++ b/erts/emulator/beam/erl_process.c
@@ -3887,21 +3887,9 @@ handle_pend_sync_suspend(Process *suspendee,
}
}
-/*
- * Like erts_pid2proc() but:
- *
- * * At least ERTS_PROC_LOCK_MAIN have to be held on c_p.
- * * At least ERTS_PROC_LOCK_MAIN have to be taken on pid.
- * * It also waits for proc to be in a state != running and garbing.
- * * If ERTS_PROC_LOCK_BUSY is returned, the calling process has to
- * yield (ERTS_BIF_YIELD[0-3]()). c_p might in this case have been
- * suspended.
- */
-
-
-Process *
-erts_pid2proc_not_running(Process *c_p, ErtsProcLocks c_p_locks,
- Eterm pid, ErtsProcLocks pid_locks)
+static Process *
+pid2proc_not_running(Process *c_p, ErtsProcLocks c_p_locks,
+ Eterm pid, ErtsProcLocks pid_locks, int suspend)
{
Process *rp;
int unlock_c_p_status;
@@ -3928,7 +3916,7 @@ erts_pid2proc_not_running(Process *c_p, ErtsProcLocks c_p_locks,
c_p->suspendee = NIL;
ASSERT(c_p->flags & F_P2PNR_RESCHED);
c_p->flags &= ~F_P2PNR_RESCHED;
- if (rp)
+ if (!suspend && rp)
resume_process(rp);
}
else {
@@ -3992,6 +3980,8 @@ erts_pid2proc_not_running(Process *c_p, ErtsProcLocks c_p_locks,
}
/* rp is not running and we got the locks we want... */
+ if (suspend)
+ suspend_process(rp_rq, rp);
}
erts_smp_runqs_unlock(cp_rq, rp_rq);
}
@@ -4004,6 +3994,35 @@ erts_pid2proc_not_running(Process *c_p, ErtsProcLocks c_p_locks,
return rp;
}
+
+/*
+ * Like erts_pid2proc() but:
+ *
+ * * At least ERTS_PROC_LOCK_MAIN have to be held on c_p.
+ * * At least ERTS_PROC_LOCK_MAIN have to be taken on pid.
+ * * It also waits for proc to be in a state != running and garbing.
+ * * If ERTS_PROC_LOCK_BUSY is returned, the calling process has to
+ * yield (ERTS_BIF_YIELD[0-3]()). c_p might in this case have been
+ * suspended.
+ */
+Process *
+erts_pid2proc_not_running(Process *c_p, ErtsProcLocks c_p_locks,
+ Eterm pid, ErtsProcLocks pid_locks)
+{
+ return pid2proc_not_running(c_p, c_p_locks, pid, pid_locks, 0);
+}
+
+/*
+ * Like erts_pid2proc_not_running(), but hands over the process
+ * in a suspended state unless (c_p is looked up).
+ */
+Process *
+erts_pid2proc_suspend(Process *c_p, ErtsProcLocks c_p_locks,
+ Eterm pid, ErtsProcLocks pid_locks)
+{
+ return pid2proc_not_running(c_p, c_p_locks, pid, pid_locks, 1);
+}
+
/*
* erts_pid2proc_nropt() is normally the same as
* erts_pid2proc_not_running(). However it is only
@@ -4117,6 +4136,21 @@ handle_pend_bif_async_suspend(Process *suspendee,
}
}
+#else
+
+/*
+ * Non-smp version of erts_pid2proc_suspend().
+ */
+Process *
+erts_pid2proc_suspend(Process *c_p, ErtsProcLocks c_p_locks,
+ Eterm pid, ErtsProcLocks pid_locks)
+{
+ Process *rp = erts_pid2proc(c_p, c_p_locks, pid, pid_locks);
+ if (rp)
+ erts_suspend(rp, pid_locks, NULL);
+ return rp;
+}
+
#endif /* ERTS_SMP */
/*
@@ -4650,7 +4684,7 @@ internal_add_to_runq(ErtsRunQueue *runq, Process *p)
if (p->status_flags & ERTS_PROC_SFLG_INRUNQ)
return NULL;
else if (p->runq_flags & ERTS_PROC_RUNQ_FLG_RUNNING) {
- ASSERT(p->rcount == 0);
+ ASSERT(ERTS_PROC_IS_EXITING(p) || p->rcount == 0);
ERTS_DBG_CHK_PROCS_RUNQ_NOPROC(runq, p);
p->status_flags |= ERTS_PROC_SFLG_PENDADD2SCHEDQ;
return NULL;
@@ -4661,7 +4695,7 @@ internal_add_to_runq(ErtsRunQueue *runq, Process *p)
ERTS_DBG_CHK_PROCS_RUNQ_NOPROC(runq, p);
#ifndef ERTS_SMP
/* Never schedule a suspended process (ok in smp case) */
- ASSERT(p->rcount == 0);
+ ASSERT(ERTS_PROC_IS_EXITING(p) || p->rcount == 0);
add_runq = runq;
#else
ASSERT(!p->bound_runq || p->bound_runq == p->run_queue);
diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h
index 334ae5573f..296acc7367 100644
--- a/erts/emulator/beam/erl_process.h
+++ b/erts/emulator/beam/erl_process.h
@@ -1535,6 +1535,10 @@ erts_get_atom_cache_map(Process *c_p)
}
#endif
+Process *erts_pid2proc_suspend(Process *,
+ ErtsProcLocks,
+ Eterm,
+ ErtsProcLocks);
#ifdef ERTS_SMP
Process *erts_pid2proc_not_running(Process *,
diff --git a/erts/emulator/sys/common/erl_mseg.c b/erts/emulator/sys/common/erl_mseg.c
index ffa3a6328c..eaef6680dd 100644
--- a/erts/emulator/sys/common/erl_mseg.c
+++ b/erts/emulator/sys/common/erl_mseg.c
@@ -134,7 +134,16 @@ static int mmap_fd;
#define CAN_PARTLY_DESTROY 0
#endif
-static const ErtsMsegOpt_t default_opt = ERTS_MSEG_DEFAULT_OPT_INITIALIZER;
+const ErtsMsegOpt_t erts_mseg_default_opt = {
+ 1, /* Use cache */
+ 1, /* Preserv data */
+ 0, /* Absolute shrink threshold */
+ 0 /* Relative shrink threshold */
+#if HALFWORD_HEAP
+ ,0 /* need low memory */
+#endif
+};
+
typedef struct cache_desc_t_ {
void *seg;
@@ -605,18 +614,10 @@ mseg_clear_cache(MemKind* mk)
INC_CC(clear_cache);
}
-static ERTS_INLINE MemKind* type2mk(ErtsAlcType_t atype)
+static ERTS_INLINE MemKind* memkind(const ErtsMsegOpt_t *opt)
{
#if HALFWORD_HEAP
- switch (atype) {
- case ERTS_ALC_A_ETS:
- case ERTS_ALC_A_BINARY:
- case ERTS_ALC_A_FIXED_SIZE:
- case ERTS_ALC_A_DRIVER:
- return &hi_mem;
- default:
- return &low_mem;
- }
+ return opt->low_mem ? &low_mem : &hi_mem;
#else
return &the_mem;
#endif
@@ -628,7 +629,7 @@ mseg_alloc(ErtsAlcType_t atype, Uint *size_p, const ErtsMsegOpt_t *opt)
Uint max, min, diff_size, size;
cache_desc_t *cd, *cand_cd;
void *seg;
- MemKind* mk = type2mk(atype);
+ MemKind* mk = memkind(opt);
INC_CC(alloc);
@@ -742,7 +743,7 @@ static void
mseg_dealloc(ErtsAlcType_t atype, void *seg, Uint size,
const ErtsMsegOpt_t *opt)
{
- MemKind* mk = type2mk(atype);
+ MemKind* mk = memkind(opt);
cache_desc_t *cd;
ERTS_MSEG_DEALLOC_STAT(mk,size);
@@ -800,7 +801,7 @@ static void *
mseg_realloc(ErtsAlcType_t atype, void *seg, Uint old_size, Uint *new_size_p,
const ErtsMsegOpt_t *opt)
{
- MemKind* mk = type2mk(atype);
+ MemKind* mk = memkind(opt);
void *new_seg;
Uint new_size;
@@ -1372,7 +1373,7 @@ erts_mseg_alloc_opt(ErtsAlcType_t atype, Uint *size_p, const ErtsMsegOpt_t *opt)
void *
erts_mseg_alloc(ErtsAlcType_t atype, Uint *size_p)
{
- return erts_mseg_alloc_opt(atype, size_p, &default_opt);
+ return erts_mseg_alloc_opt(atype, size_p, &erts_mseg_default_opt);
}
void
@@ -1387,7 +1388,7 @@ erts_mseg_dealloc_opt(ErtsAlcType_t atype, void *seg, Uint size,
void
erts_mseg_dealloc(ErtsAlcType_t atype, void *seg, Uint size)
{
- erts_mseg_dealloc_opt(atype, seg, size, &default_opt);
+ erts_mseg_dealloc_opt(atype, seg, size, &erts_mseg_default_opt);
}
void *
@@ -1405,7 +1406,7 @@ void *
erts_mseg_realloc(ErtsAlcType_t atype, void *seg, Uint old_size,
Uint *new_size_p)
{
- return erts_mseg_realloc_opt(atype, seg, old_size, new_size_p, &default_opt);
+ return erts_mseg_realloc_opt(atype, seg, old_size, new_size_p, &erts_mseg_default_opt);
}
void
diff --git a/erts/emulator/sys/common/erl_mseg.h b/erts/emulator/sys/common/erl_mseg.h
index d8053eb0d9..fbb66ee33b 100644
--- a/erts/emulator/sys/common/erl_mseg.h
+++ b/erts/emulator/sys/common/erl_mseg.h
@@ -60,15 +60,12 @@ typedef struct {
int preserv;
UWord abs_shrink_th;
UWord rel_shrink_th;
+#if HALFWORD_HEAP
+ int low_mem;
+#endif
} ErtsMsegOpt_t;
-#define ERTS_MSEG_DEFAULT_OPT_INITIALIZER \
-{ \
- 1, /* Use cache */ \
- 1, /* Preserv data */ \
- 0, /* Absolute shrink threshold */ \
- 0 /* Relative shrink threshold */ \
-}
+extern const ErtsMsegOpt_t erts_mseg_default_opt;
void *erts_mseg_alloc(ErtsAlcType_t, Uint *);
void *erts_mseg_alloc_opt(ErtsAlcType_t, Uint *, const ErtsMsegOpt_t *);
diff --git a/erts/emulator/test/process_SUITE.erl b/erts/emulator/test/process_SUITE.erl
index 36bae908aa..f68e712268 100644
--- a/erts/emulator/test/process_SUITE.erl
+++ b/erts/emulator/test/process_SUITE.erl
@@ -50,7 +50,8 @@
processes_last_call_trap/1, processes_gc_trap/1,
processes_term_proc_list/1,
otp_7738_waiting/1, otp_7738_suspended/1,
- otp_7738_resume/1]).
+ otp_7738_resume/1,
+ garb_other_running/1]).
-export([prio_server/2, prio_client/2]).
-export([init_per_testcase/2, end_per_testcase/2]).
@@ -72,7 +73,7 @@ all() ->
bad_register, garbage_collect, process_info_messages,
process_flag_badarg, process_flag_heap_size,
spawn_opt_heap_size, otp_6237, {group, processes_bif},
- {group, otp_7738}].
+ {group, otp_7738}, garb_other_running].
groups() ->
[{t_exit_2, [],
@@ -2116,6 +2117,41 @@ otp_7738_test(Type) ->
end,
?line ok.
+gor(Reds, Stop) ->
+ receive
+ {From, reds} ->
+ From ! {reds, Reds, self()},
+ gor(Reds+1, Stop);
+ {From, Stop} ->
+ From ! {stopped, Stop, Reds, self()}
+ after 0 ->
+ gor(Reds+1, Stop)
+ end.
+
+garb_other_running(Config) when is_list(Config) ->
+ ?line Stop = make_ref(),
+ ?line {Pid, Mon} = spawn_monitor(fun () -> gor(0, Stop) end),
+ ?line Reds = lists:foldl(fun (_, OldReds) ->
+ ?line erlang:garbage_collect(Pid),
+ ?line receive after 1 -> ok end,
+ ?line Pid ! {self(), reds},
+ ?line receive
+ {reds, NewReds, Pid} ->
+ ?line true = (NewReds > OldReds),
+ ?line NewReds
+ end
+ end,
+ 0,
+ lists:seq(1, 10000)),
+ ?line receive after 1 -> ok end,
+ ?line Pid ! {self(), Stop},
+ ?line receive
+ {stopped, Stop, StopReds, Pid} ->
+ ?line true = (StopReds > Reds)
+ end,
+ ?line receive {'DOWN', Mon, process, Pid, normal} -> ok end,
+ ?line ok.
+
%% Internal functions
wait_until(Fun) ->
diff --git a/erts/etc/win32/nsis/find_redist.sh b/erts/etc/win32/nsis/find_redist.sh
index 328811a0d7..bc4260ecba 100755
--- a/erts/etc/win32/nsis/find_redist.sh
+++ b/erts/etc/win32/nsis/find_redist.sh
@@ -139,8 +139,7 @@ fi
#echo $BPATH_LIST
for BP in $BPATH_LIST; do
- #echo "BP=$BP"
- for verdir in "sdk v2.0" "sdk v3.5" "v6.0A" "v7.0A" "v7.1"; do
+ for verdir in "sdk v2.0" "sdk v3.5" "v6.0A" "v7.0" "v7.0A" "v7.1"; do
BPATH=$BP
fail=false
allow_fail=false
@@ -171,6 +170,18 @@ for BP in $BPATH_LIST; do
fi
done
+# shortcut for locating vcredist_x86.exe is to put it into $ERL_TOP
+if [ -f $ERL_TOP/vcredist_x86.exe ]; then
+ echo $ERL_TOP/vcredist_x86.exe
+ exit 0
+fi
+
+# or $ERL_TOP/.. to share across multiple builds
+if [ -f $ERL_TOP/../vcredist_x86.exe ]; then
+ echo $ERL_TOP/../vcredist_x86.exe
+ exit 0
+fi
+
echo "Failed to locate vcredist_x86.exe because directory structure was unexpected" >&2
exit 3
diff --git a/erts/include/internal/erl_printf_format.h b/erts/include/internal/erl_printf_format.h
index 45818079ea..400cc7dafd 100644
--- a/erts/include/internal/erl_printf_format.h
+++ b/erts/include/internal/erl_printf_format.h
@@ -40,7 +40,7 @@ extern int erts_printf_ulong(fmtfn_t, void*, char, int, int, unsigned long);
extern int erts_printf_slong(fmtfn_t, void*, char, int, int, signed long);
extern int erts_printf_double(fmtfn_t, void *, char, int, int, double);
-extern int (*erts_printf_eterm_func)(fmtfn_t, void*, unsigned long, long);
+extern int (*erts_printf_eterm_func)(fmtfn_t, void*, unsigned long, long, unsigned long*);
#endif
diff --git a/erts/lib_src/common/erl_printf_format.c b/erts/lib_src/common/erl_printf_format.c
index 968d563325..fba3fd723c 100644
--- a/erts/lib_src/common/erl_printf_format.c
+++ b/erts/lib_src/common/erl_printf_format.c
@@ -25,7 +25,7 @@
* width: [0-9]+ | '*'
* precision: [0-9]+ | '*'
* length: hh | h | l | ll | L | j | t | b<sz>
- * conversion: d,i | o,u,x,X | e,E | f,F | g,G | a,A | c | s | T |
+ * conversion: d,i | o,u,x,X | e,E | f,F | g,G | a,A | c | s | T | R |
* p | n | %
* sz: 8 | 16 | 32 | 64 | p | e
*/
@@ -101,7 +101,7 @@
#endif
#define FMTC_d 0x0000
-#define FMTC_i 0x0001
+#define FMTC_R 0x0001
#define FMTC_o 0x0002
#define FMTC_u 0x0003
#define FMTC_x 0x0004
@@ -165,7 +165,7 @@ static char heX[] = "0123456789ABCDEF";
#define SIGN(X) ((X) > 0 ? 1 : ((X) < 0 ? -1 : 0))
#define USIGN(X) ((X) == 0 ? 0 : 1)
-int (*erts_printf_eterm_func)(fmtfn_t, void*, unsigned long, long) = NULL;
+int (*erts_printf_eterm_func)(fmtfn_t, void*, unsigned long, long, unsigned long*) = NULL;
static int
noop_fn(void *vfp, char* buf, size_t len)
@@ -183,8 +183,8 @@ static int fmt_fld(fmtfn_t fn,void* arg,
int len;
/* format the prefix */
- if ((sign || (fmt & (FMTF_sgn|FMTF_blk))) &&
- (((fmt & FMTC_MASK) == FMTC_d) || ((fmt & FMTC_MASK) == FMTC_i))) {
+ if ((sign || (fmt & (FMTF_sgn|FMTF_blk)))
+ && (fmt & FMTC_MASK) == FMTC_d) {
if (sign < 0)
*pp++ = '-';
else if ((fmt & FMTF_sgn))
@@ -245,7 +245,6 @@ static int fmt_long(fmtfn_t fn,void* arg,int sign,unsigned long uval,
switch(fmt & FMTC_MASK) {
case FMTC_d:
- case FMTC_i:
case FMTC_u:
break;
case FMTC_o:
@@ -298,7 +297,6 @@ static int fmt_long_long(fmtfn_t fn,void* arg,int sign,
switch(fmt & FMTC_MASK) {
case FMTC_d:
- case FMTC_i:
case FMTC_u:
break;
case FMTC_o:
@@ -622,7 +620,7 @@ int erts_printf_format(fmtfn_t fn, void* arg, char* fmt, va_list ap)
/* specifier */
switch(*ptr) {
case 'd': ptr++; fmt |= FMTC_d; break;
- case 'i': ptr++; fmt |= FMTC_i; break;
+ case 'i': ptr++; fmt |= FMTC_d; break;
case 'o': ptr++; fmt |= FMTC_o; break;
case 'u': ptr++; fmt |= FMTC_u; break;
case 'x': ptr++; fmt |= FMTC_x; break;
@@ -637,6 +635,7 @@ int erts_printf_format(fmtfn_t fn, void* arg, char* fmt, va_list ap)
case 'p': ptr++; fmt |= FMTC_p; break;
case 'n': ptr++; fmt |= FMTC_n; break;
case 'T': ptr++; fmt |= FMTC_T; break;
+ case 'R': ptr++; fmt |= FMTC_R; break;
case '%':
FMT(fn,arg,ptr,1,count);
ptr++;
@@ -650,7 +649,6 @@ int erts_printf_format(fmtfn_t fn, void* arg, char* fmt, va_list ap)
switch(fmt & FMTC_MASK) {
case FMTC_d:
- case FMTC_i:
switch(fmt & FMTL_MASK) {
case FMTL_hh: {
signed char tval = (signed char) va_arg(ap,int);
@@ -814,9 +812,12 @@ int erts_printf_format(fmtfn_t fn, void* arg, char* fmt, va_list ap)
default: *va_arg(ap,int*) = count; break;
}
break;
- case FMTC_T: {
+ case FMTC_T: /* Eterm */
+ case FMTC_R: { /* Eterm, Eterm* base (base ignored if !HALFWORD_HEAP) */
long prec;
unsigned long eterm;
+ unsigned long* eterm_base;
+
if (!erts_printf_eterm_func)
return -EINVAL;
if (precision < 0)
@@ -826,14 +827,16 @@ int erts_printf_format(fmtfn_t fn, void* arg, char* fmt, va_list ap)
else
prec = (long) precision;
eterm = va_arg(ap, unsigned long);
+ eterm_base = ((fmt & FMTC_MASK) == FMTC_R) ?
+ va_arg(ap, unsigned long*) : NULL;
if (width > 0 && !(fmt & FMTF_adj)) {
- res = (*erts_printf_eterm_func)(noop_fn, NULL, eterm, prec);
+ res = (*erts_printf_eterm_func)(noop_fn, NULL, eterm, prec, eterm_base);
if (res < 0)
return res;
if (width > res)
BLANKS(fn, arg, width - res, count);
}
- res = (*erts_printf_eterm_func)(fn, arg, eterm, prec);
+ res = (*erts_printf_eterm_func)(fn, arg, eterm, prec, eterm_base);
if (res < 0)
return res;
count += res;
@@ -924,7 +927,7 @@ erts_printf_slong(fmtfn_t fn, void *arg, char conv, int pad, int width,
unsigned long ul_val;
switch (conv) {
case 'd': fmt |= FMTC_d; break;
- case 'i': fmt |= FMTC_i; break;
+ case 'i': fmt |= FMTC_d; break;
case 'o': fmt |= FMTC_o; break;
case 'x': fmt |= FMTC_x; break;
case 'X': fmt |= FMTC_X; break;
diff --git a/lib/asn1/test/test_inline.erl b/lib/asn1/test/test_inline.erl
index dfa3c134ae..b7ec0d8921 100644
--- a/lib/asn1/test/test_inline.erl
+++ b/lib/asn1/test/test_inline.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -173,8 +173,8 @@ mi_encdec(N,Val) ->
m_encdec(0,_) ->
ok;
m_encdec(N,Val) ->
- {ok,B}='Mod1':encode('L',Val),
- {ok,_R}='Mod1':decode('L',B),
+ {ok,B}='Mod':encode('L',Val),
+ {ok,_R}='Mod':decode('L',B),
m_encdec(N-1,Val).
diff --git a/lib/et/src/et_wx_contents_viewer.erl b/lib/et/src/et_wx_contents_viewer.erl
index aada184a76..86f46f25d0 100644
--- a/lib/et/src/et_wx_contents_viewer.erl
+++ b/lib/et/src/et_wx_contents_viewer.erl
@@ -464,7 +464,8 @@ create_window(S) ->
wxFrame:setMenuBar(Frame,Bar),
create_file_menu(Bar),
Editor = wxTextCtrl:new(Panel, ?wxID_ANY, [{style, 0
- bor ?wxDEFAULT
+ bor ?wxDEFAULT
+ bor ?wxTE_RICH2 %% Needed on Windows
bor ?wxTE_MULTILINE
bor ?wxTE_READONLY
bor ?wxTE_DONTWRAP}]),
@@ -483,6 +484,7 @@ create_window(S) ->
wxFrame:connect(Frame, close_window, [{skip,true}]),
wxFrame:setFocus(Frame),
wxPanel:setSizer(Panel, Sizer),
+ wxSizer:fit(Sizer, Panel),
wxFrame:show(Frame),
S2#state{menu_data = HideData++SearchData++FilterData, editor = Editor, frame = Frame}.
diff --git a/lib/et/src/et_wx_viewer.erl b/lib/et/src/et_wx_viewer.erl
index d42f8c0c86..7d4286ed9d 100644
--- a/lib/et/src/et_wx_viewer.erl
+++ b/lib/et/src/et_wx_viewer.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -846,9 +846,6 @@ handle_info(#wx{event = #wxSize{size = {OldW, OldH}}} = Wx, S) ->
refresh_main_window(S4)
end,
noreply(S6);
-handle_info(#wx{event = #wxFocus{}}, S) ->
- wxWindow:setFocus(S#state.canvas), % Get keyboard focus
- noreply(S);
handle_info(#wx{event = #wxMouse{type = enter_window}}, S) ->
wxWindow:setFocus(S#state.canvas), % Get keyboard focus
noreply(S);
@@ -1252,7 +1249,6 @@ create_main_window(S) ->
Self ! Ev
end}]),
wxPanel:connect(Canvas, key_down),
- wxPanel:connect(Canvas, kill_focus),
wxPanel:connect(Canvas, enter_window, [{skip, true}]),
wxFrame:connect(Frame, command_menu_selected),
wxFrame:connect(Frame, close_window),
diff --git a/lib/kernel/doc/specs/.gitignore b/lib/kernel/doc/specs/.gitignore
new file mode 100644
index 0000000000..322eebcb06
--- /dev/null
+++ b/lib/kernel/doc/specs/.gitignore
@@ -0,0 +1 @@
+specs_*.xml
diff --git a/lib/kernel/doc/src/Makefile b/lib/kernel/doc/src/Makefile
index f8c1cac8b3..de10e31d36 100644
--- a/lib/kernel/doc/src/Makefile
+++ b/lib/kernel/doc/src/Makefile
@@ -1,19 +1,20 @@
-# ``The contents of this file are subject to the Erlang Public License,
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 1997-2011. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
-#
+# retrieved online at http://www.erlang.org/.
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
-# The Initial Developer of the Original Code is Ericsson Utvecklings AB.
-# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
-# AB. All Rights Reserved.''
-#
-# $Id$
+#
+# %CopyrightEnd%
#
include $(ERL_TOP)/make/target.mk
include $(ERL_TOP)/make/$(TARGET)/otp.mk
@@ -94,19 +95,24 @@ HTML_REF_MAN_FILE = $(HTMLDIR)/index.html
TOP_PDF_FILE = $(PDFDIR)/$(APPLICATION)-$(VSN).pdf
+SPECS_FILES = $(XML_REF3_FILES:%.xml=$(SPECDIR)/specs_%.xml)
+
+TOP_SPECS_FILE = specs.xml
# ----------------------------------------------------
# FLAGS
# ----------------------------------------------------
XML_FLAGS +=
+SPECS_FLAGS = -I../../include
+
# ----------------------------------------------------
# Targets
# ----------------------------------------------------
$(HTMLDIR)/%.gif: %.gif
$(INSTALL_DATA) $< $@
-docs: pdf html man
+docs: man pdf html
$(TOP_PDF_FILE): $(XML_FILES)
@@ -125,8 +131,22 @@ clean clean_docs:
rm -f $(MAN4DIR)/*
rm -f $(MAN6DIR)/*
rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo)
+ rm -f $(SPECDIR)/*
rm -f errs core *~
+$(SPECDIR)/specs_erl_prim_loader_stub.xml:
+ escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \
+ -o$(dir $@) -module erl_prim_loader_stub
+$(SPECDIR)/specs_erlang_stub.xml:
+ escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \
+ -o$(dir $@) -module erlang_stub
+$(SPECDIR)/specs_init_stub.xml:
+ escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \
+ -o$(dir $@) -module init_stub
+$(SPECDIR)/specs_zlib_stub.xml:
+ escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \
+ -o$(dir $@) -module zlib_stub
+
# ----------------------------------------------------
# Release Target
# ----------------------------------------------------
diff --git a/lib/kernel/doc/src/application.xml b/lib/kernel/doc/src/application.xml
index 47d578a339..51a3311ec2 100644
--- a/lib/kernel/doc/src/application.xml
+++ b/lib/kernel/doc/src/application.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2010</year>
+ <year>1996</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -50,20 +50,27 @@
<p>Refer to <seealso marker="doc/design_principles:des_princ">OTP Design Principles</seealso> for more information about
applications and behaviours.</p>
</description>
+ <datatypes>
+ <datatype>
+ <name name="start_type"/>
+ </datatype>
+ <datatype>
+ <name name="restart_type"/>
+ </datatype>
+ <datatype>
+ <!-- Parameterized opaque types are NYI: -->
+ <name><marker id="type-tuple_of">tuple_of(T)</marker></name>
+ <desc><p>A tuple where the elements are of type <c>T</c>.</p></desc>
+ </datatype>
+ </datatypes>
<funcs>
<func>
- <name>get_all_env() -> Env</name>
- <name>get_all_env(Application) -> Env</name>
+ <name name="get_all_env" arity="0"/>
+ <name name="get_all_env" arity="1"/>
<fsummary>Get the configuration parameters for an application</fsummary>
- <type>
- <v>Application = atom()</v>
- <v>Env = [{Par,Val}]</v>
- <v>&nbsp;Par = atom()</v>
- <v>&nbsp;Val = term()</v>
- </type>
<desc>
<p>Returns the configuration parameters and their values for
- <c>Application</c>. If the argument is omitted, it defaults to
+ <c><anno>Application</anno></c>. If the argument is omitted, it defaults to
the application of the calling process.</p>
<p>If the specified application is not loaded, or if the process
executing the call does not belong to any application,
@@ -71,18 +78,12 @@
</desc>
</func>
<func>
- <name>get_all_key() -> {ok, Keys} | []</name>
- <name>get_all_key(Application) -> {ok, Keys} | undefined </name>
+ <name name="get_all_key" arity="0"/>
+ <name name="get_all_key" arity="1"/>
<fsummary>Get the application specification keys</fsummary>
- <type>
- <v>Application = atom()</v>
- <v>Keys = [{Key,Val}]</v>
- <v>&nbsp;Key = atom()</v>
- <v>&nbsp;Val = term()</v>
- </type>
<desc>
<p>Returns the application specification keys and their values
- for <c>Application</c>. If the argument is omitted, it
+ for <c><anno>Application</anno></c>. If the argument is omitted, it
defaults to the application of the calling process.</p>
<p>If the specified application is not loaded, the function
returns <c>undefined</c>. If the process executing the call
@@ -91,17 +92,12 @@
</desc>
</func>
<func>
- <name>get_application() -> {ok, Application} | undefined</name>
- <name>get_application(Pid | Module) -> {ok, Application} | undefined</name>
+ <name name="get_application" arity="0"/>
+ <name name="get_application" arity="1"/>
<fsummary>Get the name of an application containing a certain process or module</fsummary>
- <type>
- <v>Pid = pid()</v>
- <v>Module = atom()</v>
- <v>Application = atom()</v>
- </type>
<desc>
<p>Returns the name of the application to which the process
- <c>Pid</c> or the module <c>Module</c> belongs. Providing no
+ <c><anno>Pid</anno></c> or the module <c><anno>Module</anno></c> belongs. Providing no
argument is the same as calling
<c>get_application(self())</c>.</p>
<p>If the specified process does not belong to any application,
@@ -110,17 +106,12 @@
</desc>
</func>
<func>
- <name>get_env(Par) -> {ok, Val} | undefined</name>
- <name>get_env(Application, Par) -> {ok, Val} | undefined</name>
+ <name name="get_env" arity="1"/>
+ <name name="get_env" arity="2"/>
<fsummary>Get the value of a configuration parameter</fsummary>
- <type>
- <v>Application = atom()</v>
- <v>Par = atom()</v>
- <v>Val = term()</v>
- </type>
<desc>
- <p>Returns the value of the configuration parameter <c>Par</c>
- for <c>Application</c>. If the application argument is
+ <p>Returns the value of the configuration parameter <c><anno>Par</anno></c>
+ for <c><anno>Application</anno></c>. If the application argument is
omitted, it defaults to the application of the calling
process.</p>
<p>If the specified application is not loaded, or
@@ -130,17 +121,12 @@
</desc>
</func>
<func>
- <name>get_key(Key) -> {ok, Val} | undefined</name>
- <name>get_key(Application, Key) -> {ok, Val} | undefined</name>
+ <name name="get_key" arity="1"/>
+ <name name="get_key" arity="2"/>
<fsummary>Get the value of an application specification key</fsummary>
- <type>
- <v>Application = atom()</v>
- <v>Key = atom()</v>
- <v>Val = term()</v>
- </type>
<desc>
<p>Returns the value of the application specification key
- <c>Key</c> for <c>Application</c>. If the application
+ <c><anno>Key</anno></c> for <c><anno>Application</anno></c>. If the application
argument is omitted, it defaults to the application of
the calling process.</p>
<p>If the specified application is not loaded, or
@@ -150,45 +136,35 @@
</desc>
</func>
<func>
- <name>load(AppDescr) -> ok | {error, Reason}</name>
- <name>load(AppDescr, Distributed) -> ok | {error, Reason}</name>
+ <name name="load" arity="1"/>
+ <name name="load" arity="2"/>
<fsummary>Load an application</fsummary>
- <type>
- <v>AppDescr = Application | AppSpec</v>
- <v>&nbsp;Application = atom()</v>
- <v>&nbsp;AppSpec = {application,Application,AppSpecKeys}</v>
- <v>&nbsp;&nbsp;AppSpec = [{Key,Val}]</v>
- <v>&nbsp;&nbsp;&nbsp;Key = atom()</v>
- <v>&nbsp;&nbsp;&nbsp;Val = term()</v>
- <v>Distributed = {Application,Nodes} | {Application,Time,Nodes} | default</v>
- <v>&nbsp;Nodes = [node() | {node(),..,node()}]</v>
- <v>&nbsp;Time = integer() > 0</v>
- <v>Reason = term()</v>
- </type>
+ <type name="application_spec"/>
+ <type name="application_opt"/>
<desc>
<p>Loads the application specification for an application into
the application controller. It will also load the application
specifications for any included applications. Note that
the function does not load the actual Erlang object code.</p>
- <p>The application can be given by its name <c>Application</c>.
+ <p>The application can be given by its name <c><anno>Application</anno></c>.
In this case the application controller will search the code
- path for the application resource file <c>Application.app</c>
+ path for the application resource file <c><anno>Application</anno>.app</c>
and load the specification it contains.</p>
<p>The application specification can also be given directly as a
- tuple <c>AppSpec</c>. This tuple should have the format and
+ tuple <c><anno>AppSpec</anno></c>. This tuple should have the format and
contents as described in <c>app(4)</c>.</p>
- <p>If <c>Distributed == {Application,[Time,]Nodes}</c>,
+ <p>If <c><anno>Distributed</anno> == {<anno>Application</anno>,[<anno>Time</anno>,]<anno>Nodes</anno>}</c>,
the application will be distributed. The argument overrides
the value for the application in the Kernel configuration
- parameter <c>distributed</c>. <c>Application</c> must be
+ parameter <c>distributed</c>. <c><anno>Application</anno></c> must be
the name of the application (same as in the first argument).
- If a node crashes and <c>Time</c> has been specified, then
- the application controller will wait for <c>Time</c>
+ If a node crashes and <c><anno>Time</anno></c> has been specified, then
+ the application controller will wait for <c><anno>Time</anno></c>
milliseconds before attempting to restart the application on
- another node. If <c>Time</c> is not specified, it will
+ another node. If <c><anno>Time</anno></c> is not specified, it will
default to 0 and the application will be restarted
immediately.</p>
- <p><c>Nodes</c> is a list of node names where the application
+ <p><c><anno>Nodes</anno></c> is a list of node names where the application
may run, in priority from left to right. Node names can be
grouped using tuples to indicate that they have the same
priority. Example:</p>
@@ -204,32 +180,22 @@ Nodes = [cp1@cave, {cp2@cave, cp3@cave}]</code>
</desc>
</func>
<func>
- <name>loaded_applications() -> [{Application, Description, Vsn}]</name>
+ <name name="loaded_applications" arity="0"/>
<fsummary>Get the currently loaded applications</fsummary>
- <type>
- <v>Application = atom()</v>
- <v>Description = string()</v>
- <v>Vsn = string()</v>
- </type>
<desc>
<p>Returns a list with information about the applications which
have been loaded using <c>load/1,2</c>, also included
- applications. <c>Application</c> is the application name.
- <c>Description</c> and <c>Vsn</c> are the values of its
+ applications. <c><anno>Application</anno></c> is the application name.
+ <c><anno>Description</anno></c> and <c><anno>Vsn</anno></c> are the values of its
<c>description</c> and <c>vsn</c> application specification
keys, respectively.</p>
</desc>
</func>
<func>
- <name>permit(Application, Bool) -> ok | {error, Reason}</name>
+ <name name="permit" arity="2"/>
<fsummary>Change an application's permission to run on a node.</fsummary>
- <type>
- <v>Application = atom()</v>
- <v>Bool = bool()</v>
- <v>Reason = term()</v>
- </type>
<desc>
- <p>Changes the permission for <c>Application</c> to run at
+ <p>Changes the permission for <c><anno>Application</anno></c> to run at
the current node. The application must have been loaded using
<c>load/1,2</c> for the function to have effect.</p>
<p>If the permission of a loaded, but not started, application
@@ -258,20 +224,14 @@ Nodes = [cp1@cave, {cp2@cave, cp3@cave}]</code>
</desc>
</func>
<func>
- <name>set_env(Application, Par, Val) -> ok</name>
- <name>set_env(Application, Par, Val, Timeout) -> ok</name>
+ <name name="set_env" arity="3"/>
+ <name name="set_env" arity="4"/>
<fsummary>Set the value of a configuration parameter</fsummary>
- <type>
- <v>Application = atom()</v>
- <v>Par = atom()</v>
- <v>Val = term()</v>
- <v>Timeout = int() | infinity</v>
- </type>
<desc>
- <p>Sets the value of the configuration parameter <c>Par</c> for
- <c>Application</c>.</p>
+ <p>Sets the value of the configuration parameter <c><anno>Par</anno></c> for
+ <c><anno>Application</anno></c>.</p>
<p><c>set_env/3</c> uses the standard <c>gen_server</c> timeout
- value (5000 ms). A <c>Timeout</c> argument can be provided
+ value (5000 ms). A <c><anno>Timeout</anno></c> argument can be provided
if another timeout value is useful, for example, in situations
where the application controller is heavily loaded.</p>
<warning>
@@ -285,20 +245,15 @@ Nodes = [cp1@cave, {cp2@cave, cp3@cave}]</code>
</desc>
</func>
<func>
- <name>start(Application) -> ok | {error, Reason}</name>
- <name>start(Application, Type) -> ok | {error, Reason}</name>
+ <name name="start" arity="1"/>
+ <name name="start" arity="2"/>
<fsummary>Load and start an application</fsummary>
- <type>
- <v>Application = atom()</v>
- <v>Type = permanent | transient | temporary</v>
- <v>Reason = term()</v>
- </type>
<desc>
- <p>Starts <c>Application</c>. If it is not loaded,
+ <p>Starts <c><anno>Application</anno></c>. If it is not loaded,
the application controller will first load it using
<c>load/1</c>. It will make sure any included applications
are loaded, but will not start them. That is assumed to be
- taken care of in the code for <c>Application</c>.</p>
+ taken care of in the code for <c><anno>Application</anno></c>.</p>
<p>The application controller checks the value of
the application specification key <c>applications</c>, to
ensure that all applications that should be started before
@@ -310,7 +265,7 @@ Nodes = [cp1@cave, {cp2@cave, cp3@cave}]</code>
The application master starts the application by calling
the application callback function <c>Module:start/2</c> as
defined by the application specification key <c>mod</c>.</p>
- <p>The <c>Type</c> argument specifies the type of
+ <p>The <c><anno>Type</anno></c> argument specifies the type of
the application. If omitted, it defaults to <c>temporary</c>.</p>
<list type="bulleted">
<item>If a permanent application terminates, all other
@@ -331,19 +286,15 @@ Nodes = [cp1@cave, {cp2@cave, cp3@cave}]</code>
</desc>
</func>
<func>
- <name>start_type() -> StartType | local | undefined</name>
+ <name name="start_type" arity="0"/>
<fsummary>Get the start type of an ongoing application startup.</fsummary>
- <type>
- <v>StartType = normal | {takeover,Node} | {failover,Node}</v>
- <v>&nbsp;Node = node()</v>
- </type>
<desc>
<p>This function is intended to be called by a process belonging
to an application, when the application is being started, to
- determine the start type which is either <c>StartType</c> or
+ determine the start type which is either <c><anno>StartType</anno></c> or
<c>local</c>.</p>
- <p>See <c>Module:start/2</c> for a description of
- <c>StartType</c>.</p>
+ <p>See <seealso marker="#start_type"><c>Module:start/2</c></seealso> for a description of
+ <c><anno>StartType</anno></c>.</p>
<p><c>local</c> is returned if only parts of the application is
being restarted (by a supervisor), or if the function is
called outside a startup.</p>
@@ -352,14 +303,10 @@ Nodes = [cp1@cave, {cp2@cave, cp3@cave}]</code>
</desc>
</func>
<func>
- <name>stop(Application) -> ok | {error, Reason}</name>
+ <name name="stop" arity="1"/>
<fsummary>Stop an application</fsummary>
- <type>
- <v>Application = atom()</v>
- <v>Reason = term()</v>
- </type>
<desc>
- <p>Stops <c>Application</c>. The application master calls
+ <p>Stops <c><anno>Application</anno></c>. The application master calls
<c>Module:prep_stop/1</c>, if such a function is defined, and
then tells the top supervisor of the application to shutdown
(see <c>supervisor(3)</c>). This means that the entire
@@ -384,16 +331,11 @@ Nodes = [cp1@cave, {cp2@cave, cp3@cave}]</code>
</desc>
</func>
<func>
- <name>takeover(Application, Type) -> ok | {error, Reason}</name>
+ <name name="takeover" arity="2"/>
<fsummary>Take over a distributed application</fsummary>
- <type>
- <v>Application = atom()</v>
- <v>Type = permanent | transient | temporary</v>
- <v>Reason = term()</v>
- </type>
<desc>
<p>Performs a takeover of the distributed application
- <c>Application</c>, which executes at another node
+ <c><anno>Application</anno></c>, which executes at another node
<c>Node</c>. At the current node, the application is
restarted by calling
<c>Module:start({takeover,Node},StartArgs)</c>. <c>Module</c>
@@ -413,14 +355,10 @@ Nodes = [cp1@cave, {cp2@cave, cp3@cave}]</code>
</desc>
</func>
<func>
- <name>unload(Application) -> ok | {error, Reason}</name>
+ <name name="unload" arity="1"/>
<fsummary>Unload an application</fsummary>
- <type>
- <v>Application = atom()</v>
- <v>Reason = term()</v>
- </type>
<desc>
- <p>Unloads the application specification for <c>Application</c>
+ <p>Unloads the application specification for <c><anno>Application</anno></c>
from the application controller. It will also unload
the application specifications for any included applications.
Note that the function does not purge the actual Erlang
@@ -428,19 +366,14 @@ Nodes = [cp1@cave, {cp2@cave, cp3@cave}]</code>
</desc>
</func>
<func>
- <name>unset_env(Application, Par) -> ok</name>
- <name>unset_env(Application, Par, Timeout) -> ok</name>
+ <name name="unset_env" arity="2"/>
+ <name name="unset_env" arity="3"/>
<fsummary>Unset the value of a configuration parameter</fsummary>
- <type>
- <v>Application = atom()</v>
- <v>Par = atom()</v>
- <v>Timeout = int() | infinity</v>
- </type>
<desc>
- <p>Removes the configuration parameter <c>Par</c> and its value
- for <c>Application</c>.</p>
+ <p>Removes the configuration parameter <c><anno>Par</anno></c> and its value
+ for <c><anno>Application</anno></c>.</p>
<p><c>unset_env/2</c> uses the standard <c>gen_server</c>
- timeout value (5000 ms). A <c>Timeout</c> argument can be
+ timeout value (5000 ms). A <c><anno>Timeout</anno></c> argument can be
provided if another timeout value is useful, for example, in
situations where the application controller is heavily loaded.</p>
<warning>
@@ -454,23 +387,17 @@ Nodes = [cp1@cave, {cp2@cave, cp3@cave}]</code>
</desc>
</func>
<func>
- <name>which_applications() -> [{Application, Description, Vsn}]</name>
- <name>which_applications(Timeout) -> [{Application, Description, Vsn}]</name>
+ <name name="which_applications" arity="0"/>
+ <name name="which_applications" arity="1"/>
<fsummary>Get the currently running applications</fsummary>
- <type>
- <v>Application = atom()</v>
- <v>Description = string()</v>
- <v>Vsn = string()</v>
- <v>Timeout = int() | infinity</v>
- </type>
<desc>
<p>Returns a list with information about the applications which
- are currently running. <c>Application</c> is the application
- name. <c>Description</c> and <c>Vsn</c> are the values of its
+ are currently running. <c><anno>Application</anno></c> is the application
+ name. <c><anno>Description</anno></c> and <c><anno>Vsn</anno></c> are the values of its
<c>description</c> and <c>vsn</c> application specification
keys, respectively.</p>
<p><c>which_applications/0</c> uses the standard
- <c>gen_server</c> timeout value (5000 ms). A <c>Timeout</c>
+ <c>gen_server</c> timeout value (5000 ms). A <c><anno>Timeout</anno></c>
argument can be provided if another timeout value is useful,
for example, in situations where the application controller
is heavily loaded.</p>
@@ -501,7 +428,7 @@ Nodes = [cp1@cave, {cp2@cave, cp3@cave}]</code>
structured according to the OTP design principles as a
supervision tree, this means starting the top supervisor of
the tree.</p>
- <p><c>StartType</c> defines the type of start:</p>
+ <p><marker id="start_type"/><c>StartType</c> defines the type of start:</p>
<list type="bulleted">
<item><c>normal</c> if it's a normal startup.</item>
<item><c>normal</c> also if the application is distributed and
@@ -532,8 +459,7 @@ Nodes = [cp1@cave, {cp2@cave, cp3@cave}]</code>
<fsummary>Extended start of an application</fsummary>
<type>
<v>Phase = atom()</v>
- <v>StartType = normal | {takeover,Node} | {failover,Node}</v>
- <v>&nbsp;Node = node()</v>
+ <v>StartType = <seealso marker="#type-start_type">start_type()</seealso></v>
<v>PhaseArgs = term()</v>
<v>Pid = pid()</v>
<v>State = state()</v>
diff --git a/lib/kernel/doc/src/auth.xml b/lib/kernel/doc/src/auth.xml
index f53fc8b29a..15d9ef0fe4 100644
--- a/lib/kernel/doc/src/auth.xml
+++ b/lib/kernel/doc/src/auth.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2009</year>
+ <year>1996</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -34,29 +34,28 @@
Cookie system, refer to
<seealso marker="doc/reference_manual:distributed">Distributed Erlang</seealso> in the Erlang Reference Manual.</p>
</description>
+ <datatypes>
+ <datatype>
+ <name name="cookie"/>
+ </datatype>
+ </datatypes>
<funcs>
<func>
- <name>is_auth(Node) -> yes | no</name>
+ <name name="is_auth" arity="1"/>
<fsummary>Status of communication authorization (deprecated)</fsummary>
- <type>
- <v>Node = node()</v>
- </type>
<desc>
- <p>Returns <c>yes</c> if communication with <c>Node</c> is
- authorized. Note that a connection to <c>Node</c> will
- be established in this case. Returns <c>no</c> if <c>Node</c>
+ <p>Returns <c>yes</c> if communication with <c><anno>Node</anno></c> is
+ authorized. Note that a connection to <c><anno>Node</anno></c> will
+ be established in this case. Returns <c>no</c> if <c><anno>Node</anno></c>
does not exist or communication is not authorized (it has
another cookie than <c>auth</c> thinks it has).</p>
- <p>Use <seealso marker="net_adm#ping/1">net_adm:ping(Node)</seealso>
+ <p>Use <seealso marker="net_adm#ping/1">net_adm:ping(<anno>Node</anno>)</seealso>
instead.</p>
</desc>
</func>
<func>
- <name>cookie() -> Cookie</name>
+ <name name="cookie" arity="0"/>
<fsummary>Magic cookie for local node (deprecated)</fsummary>
- <type>
- <v>Cookie = atom()</v>
- </type>
<desc>
<p>Use
<seealso marker="erts:erlang#erlang:get_cookie/0">erlang:get_cookie()</seealso>
@@ -64,16 +63,14 @@
</desc>
</func>
<func>
- <name>cookie(TheCookie) -> true</name>
+ <name name="cookie" arity="1"/>
<fsummary>Set the magic for the local node (deprecated)</fsummary>
- <type>
- <v>TheCookie = Cookie | [Cookie]</v>
- <d>The cookie may also be given as a list with a single atom element</d>
- <v>&nbsp;Cookie = atom()</v>
- </type>
+ <type_desc variable="TheCookie">
+ The cookie may also be given as a list with a single atom element.
+ </type_desc>
<desc>
<p>Use
- <seealso marker="erts:erlang#erlang:set_cookie/2">erlang:set_cookie(node(), Cookie)</seealso>
+ <seealso marker="erts:erlang#erlang:set_cookie/2">erlang:set_cookie(node(), <anno>Cookie</anno>)</seealso>
instead.</p>
</desc>
</func>
@@ -82,7 +79,7 @@
<fsummary>Set the magic cookie for a node and verify authorization (deprecated)</fsummary>
<type>
<v>Node = node()</v>
- <v>Cookie = atom()</v>
+ <v>Cookie = <seealso marker="#type-cookie">cookie()</seealso></v>
</type>
<desc>
<p>Equivalent to
@@ -90,18 +87,14 @@
</desc>
</func>
<func>
- <name>node_cookie(Node, Cookie) -> yes | no</name>
+ <name name="node_cookie" arity="2"/>
<fsummary>Set the magic cookie for a node and verify authorization (deprecated)</fsummary>
- <type>
- <v>Node = node()</v>
- <v>Cookie = atom()</v>
- </type>
<desc>
- <p>Sets the magic cookie of <c>Node</c> to <c>Cookie</c>, and
+ <p>Sets the magic cookie of <c><anno>Node</anno></c> to <c><anno>Cookie</anno></c>, and
verifies the status of the authorization.
Equivalent to calling
- <seealso marker="erts:erlang#erlang:set_cookie/2">erlang:set_cookie(Node, Cookie)</seealso>, followed by
- <seealso marker="#is_auth/1">auth:is_auth(Node)</seealso>.</p>
+ <seealso marker="erts:erlang#erlang:set_cookie/2">erlang:set_cookie(<anno>Node</anno>, <anno>Cookie</anno>)</seealso>, followed by
+ <seealso marker="#is_auth/1">auth:is_auth(<anno>Node</anno>)</seealso>.</p>
</desc>
</func>
</funcs>
diff --git a/lib/kernel/doc/src/code.xml b/lib/kernel/doc/src/code.xml
index 4b8f934df1..6f85388c22 100644
--- a/lib/kernel/doc/src/code.xml
+++ b/lib/kernel/doc/src/code.xml
@@ -286,6 +286,12 @@
given to <c>set_path/1</c>.</p>
</section>
+ <datatypes>
+ <datatype>
+ <name name="load_error_rsn"/>
+ </datatype>
+ </datatypes>
+
<funcs>
<func>
<name>set_path(Path) -> true | {error, What}</name>
diff --git a/lib/kernel/doc/src/disk_log.xml b/lib/kernel/doc/src/disk_log.xml
index 324d4264cf..9721907162 100644
--- a/lib/kernel/doc/src/disk_log.xml
+++ b/lib/kernel/doc/src/disk_log.xml
@@ -179,13 +179,48 @@
reopen the log simultaneously.</p>
</note>
</description>
+ <datatypes>
+ <datatype>
+ <name name="log"/>
+ </datatype>
+ <datatype>
+ <name name="dlog_size"/>
+ </datatype>
+ <datatype>
+ <name name="dlog_format"/>
+ </datatype>
+ <datatype>
+ <name name="dlog_head_opt"/>
+ </datatype>
+ <datatype>
+ <name name="dlog_byte"/>
+ </datatype>
+ <datatype>
+ <name name="dlog_mode"/>
+ </datatype>
+ <datatype>
+ <name name="dlog_type"/>
+ </datatype>
+ <datatype>
+ <name name="continuation"/>
+ <desc><p>Chunk continuation returned by
+ <c>chunk/2,3</c>, <c>bchunk/2,3</c>, or <c>chunk_step/3</c>.</p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="bytes"/>
+ </datatype>
+ <datatype>
+ <name name="invalid_header"/>
+ </datatype>
+ <datatype>
+ <name name="file_error"/>
+ </datatype>
+ </datatypes>
<funcs>
<func>
- <name>accessible_logs() -> {[LocalLog], [DistributedLog]}</name>
+ <name name="accessible_logs" arity="0"/>
<fsummary>Return the accessible disk logs on the current node.</fsummary>
- <type>
- <v>LocalLog = DistributedLog = term()</v>
- </type>
<desc>
<p>The <c>accessible_logs/0</c> function returns
the names of the disk logs accessible on the current node.
@@ -195,16 +230,13 @@
</desc>
</func>
<func>
- <name>alog(Log, Term)</name>
- <name>balog(Log, Bytes) -> ok | {error, Reason}</name>
+ <name name="alog" arity="2"/>
+ <name name="balog" arity="2"/>
+ <type variable="Log"/>
+ <type variable="Term" name_i="1"/>
+ <type variable="Bytes"/>
+ <type name="notify_ret"/>
<fsummary>Asynchronously log an item onto a disk log.</fsummary>
- <type>
- <v>Log = term()</v>
- <v>Term = term()</v>
- <v>Bytes = binary() | [Byte]</v>
- <v>Byte = [Byte] | 0 =&lt; integer() =&lt; 255</v>
- <v>Reason = no_such_log</v>
- </type>
<desc>
<p>The <c>alog/2</c> and <c>balog/2</c> functions asynchronously
append an item to a disk log. The function <c>alog/2</c> is
@@ -225,17 +257,13 @@
</desc>
</func>
<func>
- <name>alog_terms(Log, TermList)</name>
- <name>balog_terms(Log, BytesList) -> ok | {error, Reason}</name>
+ <name name="alog_terms" arity="2"/>
+ <name name="balog_terms" arity="2"/>
<fsummary>Asynchronously log several items onto a disk log.</fsummary>
- <type>
- <v>Log = term()</v>
- <v>TermList = [term()]</v>
- <v>BytesList = [Bytes]</v>
- <v>Bytes = binary() | [Byte]</v>
- <v>Byte = [Byte] | 0 =&lt; integer() =&lt; 255</v>
- <v>Reason = no_such_log</v>
- </type>
+ <type variable="Log"/>
+ <type variable="TermList" name_i="1"/>
+ <type variable="ByteList"/>
+ <type name="notify_ret"/>
<desc>
<p>The <c>alog_terms/2</c> and <c>balog_terms/2</c> functions
asynchronously append a list of items to a disk log.
@@ -257,14 +285,10 @@
</desc>
</func>
<func>
- <name>block(Log)</name>
- <name>block(Log, QueueLogRecords) -> ok | {error, Reason}</name>
+ <name name="block" arity="1"/>
+ <name name="block" arity="2"/>
+ <type name="block_error_rsn"/>
<fsummary>Block a disk log.</fsummary>
- <type>
- <v>Log = term()</v>
- <v>QueueLogRecords = bool()</v>
- <v>Reason = no_such_log | nonode | {blocked_log, Log}</v>
- </type>
<desc>
<p>With a call to <c>block/1,2</c> a process can block a log.
If the blocking process is not an owner of the log, a temporary
@@ -280,52 +304,32 @@
affected by the block. Any other attempt than those hitherto
mentioned to update or read a blocked log suspends the
calling process until the log is unblocked or returns an
- error message <c>{blocked_log, Log}</c>, depending on
- whether the value of <c>QueueLogRecords</c> is <c>true</c>
- or <c>false</c>. The default value of <c>QueueLogRecords</c>
+ error message <c>{blocked_log, <anno>Log</anno>}</c>, depending on
+ whether the value of <c><anno>QueueLogRecords</anno></c> is <c>true</c>
+ or <c>false</c>. The default value of <c><anno>QueueLogRecords</anno></c>
is <c>true</c>, which is used by <c>block/1</c>.
</p>
</desc>
</func>
<func>
- <name>change_header(Log, Header) -> ok | {error, Reason}</name>
+ <name name="change_header" arity="2"/>
<fsummary>Change the head or head_func option for an owner of a disk log.</fsummary>
- <type>
- <v>Log = term()</v>
- <v>Header = {head, Head} | {head_func, {M,F,A}}</v>
- <v>Head = none | term() | binary() | [Byte]</v>
- <v>Byte = [Byte] | 0 =&lt; integer() =&lt; 255</v>
- <v>Reason = no_such_log | nonode | {read_only_mode, Log} | {blocked_log, Log} | {badarg, head}</v>
- </type>
<desc>
<p>The <c>change_header/2</c> function changes the value of
the <c>head</c> or <c>head_func</c> option of a disk log.</p>
</desc>
</func>
<func>
- <name>change_notify(Log, Owner, Notify) -> ok | {error, Reason}</name>
+ <name name="change_notify" arity="3"/>
<fsummary>Change the notify option for an owner of a disk log.</fsummary>
- <type>
- <v>Log = term()</v>
- <v>Owner = pid()</v>
- <v>Notify = bool()</v>
- <v>Reason = no_such_log | nonode | {blocked_log, Log} | {badarg, notify} | {not_owner, Owner}</v>
- </type>
<desc>
<p>The <c>change_notify/3</c> function changes the value of the
<c>notify</c> option for an owner of a disk log. </p>
</desc>
</func>
<func>
- <name>change_size(Log, Size) -> ok | {error, Reason}</name>
+ <name name="change_size" arity="2"/>
<fsummary>Change the size of an open disk log.</fsummary>
- <type>
- <v>Log = term()</v>
- <v>Size = integer() > 0 | infinity | {MaxNoBytes, MaxNoFiles}</v>
- <v>MaxNoBytes = integer() > 0</v>
- <v>MaxNoFiles = integer() > 0</v>
- <v>Reason = no_such_log | nonode | {read_only_mode, Log} | {blocked_log, Log} | {new_size_too_small, CurrentSize} | {badarg, size} | {file_error, FileName, FileError}</v>
- </type>
<desc>
<p>The <c>change_size/2</c> function changes the size of an open log.
For a halt log it is always possible to increase the size,
@@ -363,21 +367,17 @@
</desc>
</func>
<func>
- <name>chunk(Log, Continuation)</name>
- <name>chunk(Log, Continuation, N) -> {Continuation2, Terms} | {Continuation2, Terms, Badbytes} | eof | {error, Reason}</name>
- <name>bchunk(Log, Continuation)</name>
- <name>bchunk(Log, Continuation, N) -> {Continuation2, Binaries} | {Continuation2, Binaries, Badbytes} | eof | {error, Reason}</name>
+ <name name="chunk" arity="2"/>
+ <name name="chunk" arity="3"/>
+ <name name="bchunk" arity="2"/>
+ <name name="bchunk" arity="3"/>
<fsummary>Read a chunk of items written to a disk log.</fsummary>
- <type>
- <v>Log = term()</v>
- <v>Continuation = start | cont()</v>
- <v>N = integer() > 0 | infinity</v>
- <v>Continuation2 = cont()</v>
- <v>Terms = [term()]</v>
- <v>Badbytes = integer()</v>
- <v>Reason = no_such_log | {format_external, Log} | {blocked_log, Log} | {badarg, continuation} | {not_internal_wrap, Log} | {corrupt_log_file, FileName} | {file_error, FileName, FileError}</v>
- <v>Binaries = [binary()]</v>
- </type>
+ <type variable="Log"/>
+ <type variable="Continuation"/>
+ <type variable="N"/>
+ <type name="chunk_ret"/>
+ <type name="bchunk_ret"/>
+ <type name="chunk_error_rsn"/>
<desc>
<p>The <c>chunk/2,3</c> and <c>bchunk/2,3</c> functions make
it possible to efficiently read the terms which have been
@@ -394,31 +394,31 @@
individual distributed log on some other node is chosen, if
such a log exists.
</p>
- <p>When <c>chunk/3</c> is called, <c>N</c> controls the
+ <p>When <c>chunk/3</c> is called, <c><anno>N</anno></c> controls the
maximum number of terms that are read from the log in each
chunk. Default is <c>infinity</c>, which means that all the
terms contained in the 64 kilobyte chunk are read. If less than
- <c>N</c> terms are returned, this does not necessarily mean
+ <c><anno>N</anno></c> terms are returned, this does not necessarily mean
that the end of the file has been reached.
</p>
<p>The <c>chunk</c> function returns a tuple
- <c>{Continuation2, Terms}</c>, where <c>Terms</c> is a list
- of terms found in the log. <c>Continuation2</c> is yet
+ <c>{<anno>Continuation2</anno>, <anno>Terms</anno>}</c>, where <c><anno>Terms</anno></c> is a list
+ of terms found in the log. <c><anno>Continuation2</anno></c> is yet
another continuation which must be passed on to any
subsequent calls to <c>chunk</c>. With a series of calls to
<c>chunk</c> it is possible to extract all terms from a log.
</p>
<p>The <c>chunk</c> function returns a tuple
- <c>{Continuation2, Terms, Badbytes}</c> if the log is opened
- in read-only mode and the read chunk is corrupt. <c>Badbytes</c>
+ <c>{<anno>Continuation2</anno>, <anno>Terms</anno>, <anno>Badbytes</anno>}</c> if the log is opened
+ in read-only mode and the read chunk is corrupt. <c><anno>Badbytes</anno></c>
is the number of bytes in the file which were found not to be
Erlang terms in the chunk. Note also that the log is not repaired.
When trying to read chunks from a log opened in read-write mode,
- the tuple <c>{corrupt_log_file, FileName}</c> is returned if the
+ the tuple <c>{corrupt_log_file, <anno>FileName</anno>}</c> is returned if the
read chunk is corrupt.
</p>
<p><c>chunk</c> returns <c>eof</c> when the end of the log is
- reached, or <c>{error, Reason}</c> if an error occurs. Should
+ reached, or <c>{error, <anno>Reason</anno>}</c> if an error occurs. Should
a wrap log file be missing, a message is output on the error log.
</p>
<p>When <c>chunk/2,3</c> is used with wrap logs, the returned
@@ -431,12 +431,8 @@
</desc>
</func>
<func>
- <name>chunk_info(Continuation) -> InfoList | {error, Reason}</name>
+ <name name="chunk_info" arity="1"/>
<fsummary>Return information about a chunk continuation of a disk log.</fsummary>
- <type>
- <v>Continuation = cont()</v>
- <v>Reason = {no_continuation, Continuation}</v>
- </type>
<desc>
<p>The <c>chunk_info/1</c> function returns the following pair
describing the chunk continuation returned by
@@ -444,29 +440,22 @@
</p>
<list type="bulleted">
<item>
- <p><c>{node, Node}</c>. Terms are read from
- the disk log running on <c>Node</c>.</p>
+ <p><c>{node, <anno>Node</anno>}</c>. Terms are read from
+ the disk log running on <c><anno>Node</anno></c>.</p>
</item>
</list>
</desc>
</func>
<func>
- <name>chunk_step(Log, Continuation, Step) -> {ok, Continuation2} | {error, Reason}</name>
+ <name name="chunk_step" arity="3"/>
<fsummary>Step forward or backward among the wrap log files of a disk log.</fsummary>
- <type>
- <v>Log = term()</v>
- <v>Continuation = start | cont()</v>
- <v>Step = integer()</v>
- <v>Continuation2 = cont()</v>
- <v>Reason = no_such_log | end_of_log | {format_external, Log} | {blocked_log, Log} | {badarg, continuation} | {file_error, FileName, FileError}</v>
- </type>
<desc>
<p>The function <c>chunk_step</c> can be used in conjunction
with <c>chunk/2,3</c> and <c>bchunk/2,3</c> to search
through an internally formatted wrap log. It takes as
argument a continuation as returned by <c>chunk/2,3</c>,
<c>bchunk/2,3</c>, or <c>chunk_step/3</c>, and steps forward
- (or backward) <c>Step</c> files in the wrap log. The
+ (or backward) <c><anno>Step</anno></c> files in the wrap log. The
continuation returned points to the first log item in the
new current file.
</p>
@@ -482,11 +471,9 @@
</desc>
</func>
<func>
- <name>close(Log) -> ok | {error, Reason}</name>
+ <name name="close" arity="1"/>
<fsummary>Close a disk log.</fsummary>
- <type>
- <v>Reason = no_such_log | nonode | {file_error, FileName, FileError}</v>
- </type>
+ <type name="close_error_rsn"/>
<desc>
<p> <marker id="close_1"></marker>
The function <c>close/1</c> closes a
@@ -511,11 +498,8 @@ The function <c>close/1</c> closes a
</desc>
</func>
<func>
- <name>format_error(Error) -> Chars</name>
+ <name name="format_error" arity="1"/>
<fsummary>Return an English description of a disk log error reply.</fsummary>
- <type>
- <v>Chars = [char() | Chars]</v>
- </type>
<desc>
<p>Given the error returned by any function in this module,
the function <c>format_error</c> returns a descriptive string
@@ -524,11 +508,10 @@ The function <c>close/1</c> closes a
</desc>
</func>
<func>
- <name>inc_wrap_file(Log) -> ok | {error, Reason}</name>
+ <name name="inc_wrap_file" arity="1"/>
<fsummary>Change to the next wrap log file of a disk log.</fsummary>
- <type>
- <v>Reason = no_such_log | nonode | {read_only_mode, Log} | {blocked_log, Log} | {halt_log, Log} | {invalid_header, InvalidHeader} | {file_error, FileName, FileError}</v>
- </type>
+ <type name="inc_wrap_error_rsn"/>
+ <type name="invalid_header"/>
<desc>
<p>The <c>inc_wrap_file/1</c> function forces the internally formatted
disk log to start logging to the
@@ -543,8 +526,9 @@ The function <c>close/1</c> closes a
</desc>
</func>
<func>
- <name>info(Log) -> InfoList | {error, no_such_log}</name>
+ <name name="info" arity="1"/>
<fsummary>Return information about a disk log.</fsummary>
+ <type name="dlog_info"/>
<desc>
<p>The <c>info/1</c> function returns a list of <c>{Tag, Value}</c>
pairs describing the log. If there is a disk log process running
@@ -556,55 +540,55 @@ The function <c>close/1</c> closes a
</p>
<list type="bulleted">
<item>
- <p><c>{name, Log}</c>, where <c>Log</c> is the name of
+ <p><c>{name, <anno>Log</anno>}</c>, where <c><anno>Log</anno></c> is the name of
the log as given by the <c>open/1</c> option <c>name</c>.</p>
</item>
<item>
- <p><c>{file, File}</c>. For halt logs <c>File</c> is the
- filename, and for wrap logs <c>File</c> is the base name.</p>
+ <p><c>{file, <anno>File</anno>}</c>. For halt logs <c><anno>File</anno></c> is the
+ filename, and for wrap logs <c><anno>File</anno></c> is the base name.</p>
</item>
<item>
- <p><c>{type, Type}</c>, where <c>Type</c> is the type of
+ <p><c>{type, <anno>Type</anno>}</c>, where <c><anno>Type</anno></c> is the type of
the log as given by the <c>open/1</c> option <c>type</c>.</p>
</item>
<item>
- <p><c>{format, Format}</c>, where <c>Format</c> is the format
+ <p><c>{format, <anno>Format</anno>}</c>, where <c><anno>Format</anno></c> is the format
of the log as given by the <c>open/1</c> option <c>format</c>.</p>
</item>
<item>
- <p><c>{size, Size}</c>, where <c>Size</c> is the size
+ <p><c>{size, <anno>Size</anno>}</c>, where <c><anno>Size</anno></c> is the size
of the log as given by the <c>open/1</c> option <c>size</c>,
or the size set by <c>change_size/2</c>. The value set by
<c>change_size/2</c> is reflected immediately.</p>
</item>
<item>
- <p><c>{mode, Mode}</c>, where <c>Mode</c> is the mode
+ <p><c>{mode, <anno>Mode</anno>}</c>, where <c><anno>Mode</anno></c> is the mode
of the log as given by the <c>open/1</c> option <c>mode</c>.</p>
</item>
<item>
- <p><c>{owners, [{pid(), Notify}]}</c> where <c>Notify</c>
+ <p><c>{owners, [{pid(), <anno>Notify</anno>}]}</c> where <c><anno>Notify</anno></c>
is the value set by the <c>open/1</c> option <c>notify</c>
or the function <c>change_notify/3</c> for the owners of
the log.</p>
</item>
<item>
- <p><c>{users, Users}</c> where <c>Users</c> is the number
+ <p><c>{users, <anno>Users</anno>}</c> where <c><anno>Users</anno></c> is the number
of anonymous users of the log, see the <c>open/1</c> option
<seealso marker="#linkto">linkto</seealso>.</p>
</item>
<item>
- <p><c>{status, Status}</c>, where <c>Status</c> is <c>ok</c>
- or <c>{blocked, QueueLogRecords}</c> as set by the functions
+ <p><c>{status, <anno>Status</anno>}</c>, where <c><anno>Status</anno></c> is <c>ok</c>
+ or <c>{blocked, <anno>QueueLogRecords</anno>}</c> as set by the functions
<c>block/1,2</c> and <c>unblock/1</c>.</p>
</item>
<item>
- <p><c>{node, Node}</c>. The information returned by the
+ <p><c>{node, <anno>Node</anno>}</c>. The information returned by the
current invocation of the <c>info/1</c> function has been
- gathered from the disk log process running on <c>Node</c>.</p>
+ gathered from the disk log process running on <c><anno>Node</anno></c>.</p>
</item>
<item>
- <p><c>{distributed, Dist}</c>. If the log is local on
- the current node, then <c>Dist</c> has the value <c>local</c>,
+ <p><c>{distributed, <anno>Dist</anno>}</c>. If the log is local on
+ the current node, then <c><anno>Dist</anno></c> has the value <c>local</c>,
otherwise all nodes where the log is distributed
are returned as a list.</p>
</item>
@@ -614,16 +598,16 @@ The function <c>close/1</c> closes a
</p>
<list type="bulleted">
<item>
- <p><c>{head, Head}</c>. Depending of the value of
+ <p><c>{head, <anno>Head</anno>}</c>. Depending of the value of
the <c>open/1</c> options <c>head</c> and <c>head_func</c>
or set by the function <c>change_header/2</c>, the value
- of <c>Head</c> is <c>none</c> (default),
+ of <c><anno>Head</anno></c> is <c>none</c> (default),
<c>{head, H}</c> (<c>head</c> option) or <c>{M,F,A}</c>
(<c>head_func</c> option).</p>
</item>
<item>
- <p><c>{no_written_items, NoWrittenItems}</c>, where
- <c>NoWrittenItems</c> is the number of items
+ <p><c>{no_written_items, <anno>NoWrittenItems</anno>}</c>, where
+ <c><anno>NoWrittenItems</anno></c> is the number of items
written to the log since the disk log process was created.</p>
</item>
</list>
@@ -632,7 +616,7 @@ The function <c>close/1</c> closes a
</p>
<list type="bulleted">
<item>
- <p><c>{full, Full}</c>, where <c>Full</c> is <c>true</c> or
+ <p><c>{full, <anno>Full</anno>}</c>, where <c><anno>Full</anno></c> is <c>true</c> or
<c>false</c> depending on whether the halt log is full or not.</p>
</item>
</list>
@@ -660,8 +644,8 @@ The function <c>close/1</c> closes a
<c>size</c> or set by <c>change_size/2</c>.</p>
</item>
<item>
- <p><c>{no_overflows, {SinceLogWasOpened, SinceLastInfo}}</c>,
- where <c>SinceLogWasOpened</c> (<c>SinceLastInfo</c>) is
+ <p><c>{no_overflows, {<anno>SinceLogWasOpened</anno>, <anno>SinceLastInfo</anno>}}</c>,
+ where <c><anno>SinceLogWasOpened</anno></c> (<c><anno>SinceLastInfo</anno></c>) is
the number of times a wrap log file has been filled up and a
new one opened or <c>inc_wrap_file/1</c> has been called since
the disk log was last opened (<c>info/1</c>
@@ -677,21 +661,18 @@ The function <c>close/1</c> closes a
</desc>
</func>
<func>
- <name>lclose(Log)</name>
- <name>lclose(Log, Node) -> ok | {error, Reason}</name>
+ <name name="lclose" arity="1"/>
+ <name name="lclose" arity="2"/>
+ <type name="lclose_error_rsn"/>
<fsummary>Close a disk log on one node.</fsummary>
- <type>
- <v>Node = node()</v>
- <v>Reason = no_such_log | {file_error, FileName, FileError}</v>
- </type>
<desc>
<p>The function <c>lclose/1</c> closes a local log or an
individual distributed log on the current node.
The function <c>lclose/2</c> closes an individual
distributed log on the specified node if the node
is not the current one.
- <c>lclose(Log)</c> is equivalent to
- <c>lclose(Log,&nbsp;node())</c>.
+ <c>lclose(<anno>Log</anno>)</c> is equivalent to
+ <c>lclose(<anno>Log</anno>,&nbsp;node())</c>.
See also <seealso marker="#close_1">close/1</seealso>.
</p>
<p>If there is no log with the given name
@@ -700,20 +681,17 @@ The function <c>close/1</c> closes a
</desc>
</func>
<func>
- <name>log(Log, Term)</name>
- <name>blog(Log, Bytes) -> ok | {error, Reason}</name>
+ <name name="log" arity="2"/>
+ <name name="blog" arity="2"/>
<fsummary>Log an item onto a disk log.</fsummary>
- <type>
- <v>Log = term()</v>
- <v>Term = term()</v>
- <v>Bytes = binary() | [Byte]</v>
- <v>Byte = [Byte] | 0 =&lt; integer() =&lt; 255</v>
- <v>Reason = no_such_log | nonode | {read_only_mode, Log} | {format_external, Log} | {blocked_log, Log} | {full, Log} | {invalid_header, InvalidHeader} | {file_error, FileName, FileError}</v>
- </type>
+ <type variable="Log"/>
+ <type variable="Term" name_i="1"/>
+ <type variable="Bytes"/>
+ <type name="log_error_rsn"/>
<desc>
<p>The <c>log/2</c> and <c>blog/2</c> functions synchronously
append a term to a disk log. They return <c>ok</c> or
- <c>{error, Reason}</c> when the term has been written to
+ <c>{error, <anno>Reason</anno>}</c> when the term has been written to
disk. If the log is distributed, <c>ok</c> is always
returned, unless all nodes are down. Terms are written by
means of the ordinary <c>write()</c> function of the
@@ -736,17 +714,13 @@ The function <c>close/1</c> closes a
</desc>
</func>
<func>
- <name>log_terms(Log, TermList)</name>
- <name>blog_terms(Log, BytesList) -> ok | {error, Reason}</name>
+ <name name="log_terms" arity="2"/>
+ <name name="blog_terms" arity="2"/>
<fsummary>Log several items onto a disk log.</fsummary>
- <type>
- <v>Log = term()</v>
- <v>TermList = [term()]</v>
- <v>BytesList = [Bytes]</v>
- <v>Bytes = binary() | [Byte]</v>
- <v>Byte = [Byte] | 0 =&lt; integer() =&lt; 255</v>
- <v>Reason = no_such_log | nonode | {read_only_mode, Log} | {format_external, Log} | {blocked_log, Log} | {full, Log} | {invalid_header, InvalidHeader} | {file_error, FileName, FileError}</v>
- </type>
+ <type variable="Log"/>
+ <type variable="TermList" name_i="1"/>
+ <type variable="BytesList"/>
+ <type name="log_error_rsn"/>
<desc>
<p>The <c>log_terms/2</c> and <c>blog_terms/2</c> functions
synchronously append a list of items to the log. The benefit
@@ -769,47 +743,33 @@ The function <c>close/1</c> closes a
</desc>
</func>
<func>
- <name>open(ArgL) -> OpenRet | DistOpenRet</name>
+ <name name="open" arity="1"/>
+ <type name="dlog_options"/>
+ <type name="dlog_option"/>
+ <type name="open_ret"/>
+ <type name="ret"/>
+ <type name="dist_open_ret"/>
+ <type name="dist_error_rsn"/>
+ <type name="open_error_rsn"/>
+ <type name="dlog_optattr"/>
+ <type name="dlog_size"/>
<fsummary>Open a disk log file.</fsummary>
- <type>
- <v>ArgL = [Opt]</v>
- <v>Opt = {name, term()} | {file, FileName}, {linkto, LinkTo} | {repair, Repair} | {type, Type} | {format, Format} | {size, Size} | {distributed, [Node]} | {notify, bool()} | {head, Head} | {head_func, {M,F,A}} | {mode, Mode}</v>
- <v>FileName = string() | atom()</v>
- <v>LinkTo = pid() | none</v>
- <v>Repair = true | false | truncate</v>
- <v>Type = halt | wrap</v>
- <v>Format = internal | external</v>
- <v>Size = integer() > 0 | infinity | {MaxNoBytes, MaxNoFiles}</v>
- <v>MaxNoBytes = integer() > 0</v>
- <v>MaxNoFiles = 0 &lt; integer() &lt; 65000</v>
- <v>Rec = integer()</v>
- <v>Bad = integer()</v>
- <v>Head = none | term() | binary() | [Byte]</v>
- <v>Byte = [Byte] | 0 =&lt; integer() =&lt; 255</v>
- <v>Mode = read_write | read_only</v>
- <v>OpenRet = Ret | {error, Reason}</v>
- <v>DistOpenRet = {[{Node, Ret}], [{BadNode, {error, DistReason}}]}</v>
- <v>Node = BadNode = atom()</v>
- <v>Ret = {ok, Log} | {repaired, Log, {recovered, Rec}, {badbytes, Bad}}</v>
- <v>DistReason = nodedown | Reason</v>
- <v>Reason = no_such_log | {badarg, Arg} | {size_mismatch, CurrentSize, NewSize} | {arg_mismatch, OptionName, CurrentValue, Value} | {name_already_open, Log} | {open_read_write, Log} | {open_read_only, Log} | {need_repair, Log} | {not_a_log_file, FileName} | {invalid_index_file, FileName} | {invalid_header, InvalidHeader} | {file_error, FileName, FileError} | {node_already_open, Log}</v>
- </type>
<desc>
- <p>The <c>ArgL</c> parameter is a list of options which have
+ <p>The <c><anno>ArgL</anno></c> parameter is a list of options which have
the following meanings:</p>
<list type="bulleted">
<item>
- <p><c>{name, Log}</c> specifies the name of the log.
+ <p><c>{name, <anno>Log</anno>}</c> specifies the name of the log.
This is the name which must be passed on as a parameter in
all subsequent logging operations. A name must always
be supplied.
</p>
</item>
<item>
- <p><c>{file, FileName}</c> specifies the name of the
+ <p><c>{file, <anno>FileName</anno>}</c> specifies the name of the
file which will be used for logged terms. If this value is
omitted and the name of the log is either an atom or a string,
- the file name will default to <c>lists:concat([Log, ".LOG"])</c> for halt logs. For wrap logs, this will be
+ the file name will default to <c>lists:concat([<anno>Log</anno>, ".LOG"])</c> for halt logs. For wrap logs, this will be
the base name of the files. Each file in a wrap log
will be called <c><![CDATA[<base_name>.N]]></c>, where <c>N</c> is an
integer. Each wrap log will also have two files called
@@ -817,22 +777,22 @@ The function <c>close/1</c> closes a
</p>
</item>
<item>
- <p><c>{linkto, LinkTo}</c>. <marker id="linkto"></marker>
+ <p><c>{linkto, <anno>LinkTo</anno>}</c>. <marker id="linkto"></marker>
If
- <c>LinkTo</c> is a pid, that pid becomes an owner of the
- log. If <c>LinkTo</c> is <c>none</c> the log records
+ <c><anno>LinkTo</anno></c> is a pid, that pid becomes an owner of the
+ log. If <c><anno>LinkTo</anno></c> is <c>none</c> the log records
that it is used anonymously by some process by
incrementing the <c>users</c> counter. By default, the
process which calls <c>open/1</c> owns the log.
</p>
</item>
<item>
- <p><c>{repair, Repair}</c>. If <c>Repair</c> is <c>true</c>,
+ <p><c>{repair, <anno>Repair</anno>}</c>. If <c><anno>Repair</anno></c> is <c>true</c>,
the current log file will be repaired, if needed. As the
restoration is initiated, a message is output on the error log.
If <c>false</c> is given,
no automatic repair will be attempted. Instead, the
- tuple <c>{error, {need_repair, Log}}</c> is returned if an
+ tuple <c>{error, {need_repair, <anno>Log</anno>}}</c> is returned if an
attempt is made to open a corrupt log file.
If <c>truncate</c> is given, the log file will
be truncated, creating an empty log. Default is
@@ -841,41 +801,41 @@ If
</p>
</item>
<item>
- <p><c>{type, Type}</c> is the type of the log. Default
+ <p><c>{type, <anno>Type</anno>}</c> is the type of the log. Default
is <c>halt</c>.
</p>
</item>
<item>
- <p><c>{format, Format}</c> specifies the format of the
+ <p><c>{format, <anno>Format</anno>}</c> specifies the format of the
disk log. Default is <c>internal</c>.
</p>
</item>
<item>
- <p><c>{size, Size}</c> specifies the size of the log.
+ <p><c>{size, <anno>Size</anno>}</c> specifies the size of the log.
When a halt log has reached its maximum size, all attempts to
log more items are rejected. The default size is
<c>infinity</c>, which for halt implies that there is no
- maximum size. For wrap logs, the <c>Size</c> parameter
+ maximum size. For wrap logs, the <c><anno>Size</anno></c> parameter
may be either a pair
- <c>{MaxNoBytes, MaxNoFiles}</c> or <c>infinity</c>. In the
+ <c>{<anno>MaxNoBytes</anno>, <anno>MaxNoFiles</anno>}</c> or <c>infinity</c>. In the
latter case, if the files of an already existing wrap log
with the same name can be found, the size is read
from the existing wrap log, otherwise an error is returned.
- Wrap logs write at most <c>MaxNoBytes</c> bytes on each file
- and use <c>MaxNoFiles</c> files before starting all over with
- the first wrap log file. Regardless of <c>MaxNoBytes</c>,
+ Wrap logs write at most <c><anno>MaxNoBytes</anno></c> bytes on each file
+ and use <c><anno>MaxNoFiles</anno></c> files before starting all over with
+ the first wrap log file. Regardless of <c><anno>MaxNoBytes</anno></c>,
at least the header (if there is one) and one
item is written on each wrap log file before
wrapping to the next file.
When opening an existing wrap log, it is not
necessary to supply a value for the option <c>Size</c>, but any
supplied value must equal the current size of the log, otherwise
- the tuple <c>{error, {size_mismatch, CurrentSize, NewSize}}</c>
+ the tuple <c>{error, {size_mismatch, <anno>CurrentSize</anno>, <anno>NewSize</anno>}}</c>
is returned.
</p>
</item>
<item>
- <p><c>{distributed, Nodes}</c>. This option can be used for
+ <p><c>{distributed, <anno>Nodes</anno>}</c>. This option can be used for
adding members to a distributed disk log. The
default value is <c>[]</c>, which means that
the log is local on the current node.
@@ -946,10 +906,10 @@ If
</list>
</item>
<item>
- <p><c>{head, Head}</c> specifies a header to be
+ <p><c>{head, <anno>Head</anno>}</c> specifies a header to be
written first on the log file. If the log is a wrap
- log, the item <c>Head</c> is written first in each new file.
- <c>Head</c> should be a term if the format is
+ log, the item <c><anno>Head</anno></c> is written first in each new file.
+ <c><anno>Head</anno></c> should be a term if the format is
<c>internal</c>, and a deep list of bytes (or a binary)
otherwise. Default is <c>none</c>, which means that
no header is written first on the file.
@@ -966,17 +926,17 @@ If
</p>
</item>
<item>
- <p><c>{mode, Mode}</c> specifies if the log is to be
+ <p><c>{mode, <anno>Mode</anno>}</c> specifies if the log is to be
opened in read-only or read-write mode. It defaults to
<c>read_write</c>.
</p>
</item>
</list>
- <p>The <c>open/1</c> function returns <c>{ok, Log}</c> if the
+ <p>The <c>open/1</c> function returns <c>{ok, <anno>Log</anno>}</c> if the
log file was successfully opened. If the file was
- successfully repaired, the tuple <c>{repaired, Log, {recovered, Rec}, {badbytes, Bad}}</c> is returned, where
- <c>Rec</c> is the number of whole Erlang terms found in the
- file and <c>Bad</c> is the number of bytes in the file which
+ successfully repaired, the tuple <c>{repaired, <anno>Log</anno>, {recovered, <anno>Rec</anno>}, {badbytes, <anno>Bad</anno>}}</c> is returned, where
+ <c><anno>Rec</anno></c> is the number of whole Erlang terms found in the
+ file and <c><anno>Bad</anno></c> is the number of bytes in the file which
were non-Erlang terms. If the <c>distributed</c> parameter
was given, <c>open/1</c> returns a list of
successful replies and a list of erroneous replies. Each
@@ -988,7 +948,7 @@ If
position after the last logged item, and the logging of items
will commence from there. If the format is <c>internal</c>
and the existing file is not recognized as an internally
- formatted log, a tuple <c>{error, {not_a_log_file, FileName}}</c>
+ formatted log, a tuple <c>{error, {not_a_log_file, <anno>FileName</anno>}}</c>
is returned.
</p>
<p>The <c>open/1</c> function cannot be used for changing the
@@ -1000,15 +960,15 @@ If
or <c>change_size/2</c>. As a consequence,
none of the options except <c>name</c> is mandatory. If some
given value differs from the current value, a tuple
- <c>{error, {arg_mismatch, OptionName, CurrentValue, Value}}</c>
+ <c>{error, {arg_mismatch, <anno>OptionName</anno>, <anno>CurrentValue</anno>, <anno>Value</anno>}}</c>
is returned. Caution: an owner's attempt to open a log
as owner once again is acknowledged with the return value
- <c>{ok, Log}</c>, but the state of the disk log is not
+ <c>{ok, <anno>Log</anno>}</c>, but the state of the disk log is not
affected in any way.
</p>
<p>If a log with a given name is local on some node,
and one tries to open the log distributed on the same node,
- then the tuple <c>{error, {node_already_open, Name}}</c> is
+ then the tuple <c>{error, {node_already_open, <anno>Log</anno>}}</c> is
returned. The same tuple is returned if the log is distributed on
some node, and one tries to open the log locally on the same node.
Opening individual distributed disk logs for the first time
@@ -1036,12 +996,8 @@ If
</desc>
</func>
<func>
- <name>pid2name(Pid) -> {ok, Log} | undefined</name>
+ <name name="pid2name" arity="1"/>
<fsummary>Return the name of the disk log handled by a pid.</fsummary>
- <type>
- <v>Log = term()</v>
- <v>Pid = pid()</v>
- </type>
<desc>
<p>The <c>pid2name/1</c> function returns the name of the log
given the pid of a disk log process on the current node, or
@@ -1052,26 +1008,23 @@ If
</desc>
</func>
<func>
- <name>reopen(Log, File)</name>
- <name>reopen(Log, File, Head)</name>
- <name>breopen(Log, File, BHead) -> ok | {error, Reason}</name>
+ <name name="reopen" arity="2"/>
+ <name name="reopen" arity="3"/>
+ <name name="breopen" arity="3"/>
<fsummary>Reopen a disk log and save the old log.</fsummary>
- <type>
- <v>Log = term()</v>
- <v>File = string()</v>
- <v>Head = term()</v>
- <v>BHead = binary() | [Byte]</v>
- <v>Byte = [Byte] | 0 =&lt; integer() =&lt; 255</v>
- <v>Reason = no_such_log | nonode | {read_only_mode, Log} | {blocked_log, Log} | {same_file_name, Log} | {invalid_index_file, FileName} | {invalid_header, InvalidHeader} | {file_error, FileName, FileError}</v>
- </type>
+ <type variable="Log"/>
+ <type variable="File" name_i="1"/>
+ <type variable="Head" name_i="2"/>
+ <type variable="BHead"/>
+ <type name="reopen_error_rsn"/>
<desc>
<p>The <c>reopen</c> functions first rename the log file
- to <c>File</c> and then re-create a new log file.
- In case of a wrap log, <c>File</c> is used as the base name
+ to <c><anno>File</anno></c> and then re-create a new log file.
+ In case of a wrap log, <c><anno>File</anno></c> is used as the base name
of the renamed files.
By default the header given to <c>open/1</c> is written first in
- the newly opened log file, but if the <c>Head</c> or the
- <c>BHead</c> argument is given, this item is used instead.
+ the newly opened log file, but if the <c><anno>Head</anno></c> or the
+ <c><anno>BHead</anno></c> argument is given, this item is used instead.
The header argument is used once only; next time a wrap log file
is opened, the header given to <c>open/1</c> is used.
</p>
@@ -1089,12 +1042,9 @@ If
</desc>
</func>
<func>
- <name>sync(Log) -> ok | {error, Reason}</name>
+ <name name="sync" arity="1"/>
+ <type name="sync_error_rsn"/>
<fsummary>Flush the contents of a disk log to the disk.</fsummary>
- <type>
- <v>Log = term()</v>
- <v>Reason = no_such_log | nonode | {read_only_mode, Log} | {blocked_log, Log} | {file_error, FileName, FileError}</v>
- </type>
<desc>
<p>The <c>sync/1</c> function ensures that the contents of the
log are actually written to the disk.
@@ -1103,20 +1053,17 @@ If
</desc>
</func>
<func>
- <name>truncate(Log)</name>
- <name>truncate(Log, Head)</name>
- <name>btruncate(Log, BHead) -> ok | {error, Reason}</name>
+ <name name="truncate" arity="1"/>
+ <name name="truncate" arity="2"/>
+ <name name="btruncate" arity="2"/>
<fsummary>Truncate a disk log.</fsummary>
- <type>
- <v>Log = term()</v>
- <v>Head = term()</v>
- <v>BHead = binary() | [Byte]</v>
- <v>Byte = [Byte] | 0 =&lt; integer() =&lt; 255</v>
- <v>Reason = no_such_log | nonode | {read_only_mode, Log} | {blocked_log, Log} | {invalid_header, InvalidHeader} | {file_error, FileName, FileError}</v>
- </type>
+ <type variable="Log"/>
+ <type variable="Head" name_i="2"/>
+ <type variable="BHead"/>
+ <type name="trunc_error_rsn"/>
<desc>
<p>The <c>truncate</c> functions remove all items from a disk log.
- If the <c>Head</c> or the <c>BHead</c> argument is
+ If the <c><anno>Head</anno></c> or the <c><anno>BHead</anno></c> argument is
given, this item is written first in the newly truncated
log, otherwise the header given to <c>open/1</c> is used.
The header argument is only used once; next time a wrap log file
@@ -1138,12 +1085,9 @@ If
</desc>
</func>
<func>
- <name>unblock(Log) -> ok | {error, Reason}</name>
+ <name name="unblock" arity="1"/>
+ <type name="unblock_error_rsn"/>
<fsummary>Unblock a disk log.</fsummary>
- <type>
- <v>Log = term()</v>
- <v>Reason = no_such_log | nonode | {not_blocked, Log} | {not_blocked_by_pid, Log}</v>
- </type>
<desc>
<p>The <c>unblock/1</c> function unblocks a log.
A log can only be unblocked by the blocking process.
@@ -1159,4 +1103,3 @@ If
<seealso marker="wrap_log_reader">wrap_log_reader(3)</seealso></p>
</section>
</erlref>
-
diff --git a/lib/kernel/doc/src/erl_boot_server.xml b/lib/kernel/doc/src/erl_boot_server.xml
index 4e7533810e..472671a80e 100644
--- a/lib/kernel/doc/src/erl_boot_server.xml
+++ b/lib/kernel/doc/src/erl_boot_server.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2009</year>
+ <year>1996</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -49,29 +49,17 @@
</description>
<funcs>
<func>
- <name>start(Slaves) -> {ok, Pid} | {error, What}</name>
+ <name name="start" arity="1"/>
<fsummary>Start the boot server</fsummary>
- <type>
- <v>Slaves = [Host]</v>
- <v>Host = atom()</v>
- <v>Pid = pid()</v>
- <v>What = term()</v>
- </type>
<desc>
- <p>Starts the boot server. <c>Slaves</c> is a list of IP
+ <p>Starts the boot server. <c><anno>Slaves</anno></c> is a list of IP
addresses for hosts which are allowed to use this server as a
boot server.</p>
</desc>
</func>
<func>
- <name>start_link(Slaves) -> {ok, Pid} | {error, What}</name>
+ <name name="start_link" arity="1"/>
<fsummary>Start the boot server and links the caller</fsummary>
- <type>
- <v>Slaves = [Host]</v>
- <v>Host = atom()</v>
- <v>Pid = pid()</v>
- <v>What = term()()</v>
- </type>
<desc>
<p>Starts the boot server and links to the caller. This function
is used to start the server if it is included in a supervision
@@ -79,37 +67,23 @@
</desc>
</func>
<func>
- <name>add_slave(Slave) -> ok | {error, What}</name>
+ <name name="add_slave" arity="1"/>
<fsummary>Add a slave to the list of allowed slaves</fsummary>
- <type>
- <v>Slave = Host</v>
- <v>Host = atom()</v>
- <v>What = term()</v>
- </type>
<desc>
- <p>Adds a <c>Slave</c> node to the list of allowed slave hosts.</p>
+ <p>Adds a <c><anno>Slave</anno></c> node to the list of allowed slave hosts.</p>
</desc>
</func>
<func>
- <name>delete_slave(Slave) -> ok | {error, What}</name>
+ <name name="delete_slave" arity="1"/>
<fsummary>Delete a slave from the list of allowed slaves</fsummary>
- <type>
- <v>Slave = Host</v>
- <v>Host = atom()</v>
- <v>What = void()</v>
- </type>
<desc>
- <p>Deletes a <c>Slave</c> node from the list of allowed slave
+ <p>Deletes a <c><anno>Slave</anno></c> node from the list of allowed slave
hosts.</p>
</desc>
</func>
<func>
- <name>which_slaves() -> Slaves</name>
+ <name name="which_slaves" arity="0"/>
<fsummary>Return the current list of allowed slave hosts</fsummary>
- <type>
- <v>Slaves = [Host]</v>
- <v>Host = atom()</v>
- </type>
<desc>
<p>Returns the current list of allowed slave hosts.</p>
</desc>
diff --git a/lib/kernel/doc/src/erl_ddll.xml b/lib/kernel/doc/src/erl_ddll.xml
index 9a62b45d63..f9514dda2f 100644
--- a/lib/kernel/doc/src/erl_ddll.xml
+++ b/lib/kernel/doc/src/erl_ddll.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1997</year><year>2010</year>
+ <year>1997</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -172,6 +172,14 @@
</item>
</taglist>
</description>
+ <datatypes>
+ <datatype>
+ <name name="driver"/>
+ </datatype>
+ <datatype>
+ <name name="path"/>
+ </datatype>
+ </datatypes>
<funcs>
<func>
<name>demonitor(MonitorRef) -> ok</name>
@@ -189,37 +197,21 @@
</desc>
</func>
<func>
- <name>info() -> AllInfoList</name>
+ <name name="info" arity="0"/>
<fsummary>Retrieve information about all drivers</fsummary>
- <type>
- <v>AllInfoList = [ DriverInfo ]</v>
- <v>DriverInfo = {DriverName, InfoList}</v>
- <v>DriverName = string()</v>
- <v>InfoList = [ InfoItem ]</v>
- <v>InfoItem = {Tag, Value}</v>
- <v>Tag = atom()</v>
- <v>Value = term()</v>
- </type>
<desc>
- <p>Returns a list of tuples <c>{DriverName, InfoList}</c>, where
- <c>InfoList</c> is the result of calling <seealso marker="#info/1">info/1</seealso> for that
- <c>DriverName</c>. Only dynamically linked in drivers are
+ <p>Returns a list of tuples <c>{<anno>DriverName</anno>, <anno>InfoList</anno>}</c>, where
+ <c><anno>InfoList</anno></c> is the result of calling <seealso marker="#info/1">info/1</seealso> for that
+ <c><anno>DriverName</anno></c>. Only dynamically linked in drivers are
included in the list.</p>
</desc>
</func>
<func>
- <name>info(Name) -> InfoList</name>
+ <name name="info" arity="1"/>
<fsummary>Retrieve information about one driver</fsummary>
- <type>
- <v>Name = string() | atom()</v>
- <v>InfoList = [ InfoItem ]</v>
- <v>InfoItem = {Tag, Value}</v>
- <v>Tag = atom()</v>
- <v>Value = term()</v>
- </type>
<desc>
- <p>Returns a list of tuples <c>{Tag, Value}</c>, where
- <c>Tag</c> is the information item and <c>Value</c> is the result
+ <p>Returns a list of tuples <c>{<anno>Tag</anno>, <anno>Value</anno>}</c>, where
+ <c><anno>Tag</anno></c> is the information item and <c><anno>Value</anno></c> is the result
of calling <seealso marker="#info/2">info/2</seealso> with this driver name and
this tag. The result being a tuple list containing all
information available about a driver. </p>
@@ -305,22 +297,18 @@
</desc>
</func>
<func>
- <name>load(Path, Name) -> ok | {error, ErrorDesc}</name>
+ <name name="load" arity="2"/>
<fsummary>Load a driver</fsummary>
- <type>
- <v>Path = Name = string() | atom()</v>
- <v>ErrorDesc = term()</v>
- </type>
<desc>
- <p>Loads and links the dynamic driver <c>Name</c>. <c>Path</c>
+ <p>Loads and links the dynamic driver <c><anno>Name</anno></c>. <c><anno>Path</anno></c>
is a file path to the directory containing the driver.
- <c>Name</c> must be a sharable object/dynamic library. Two
- drivers with different <c>Path</c> parameters cannot be
- loaded under the same name. The <c>Name</c> is a string or
+ <c><anno>Name</anno></c> must be a sharable object/dynamic library. Two
+ drivers with different <c><anno>Path</anno></c> parameters cannot be
+ loaded under the same name. The <c><anno>Name</anno></c> is a string or
atom containing at least one character.</p>
- <p>The <c>Name</c> given should correspond to the filename
+ <p>The <c><anno>Name</anno></c> given should correspond to the filename
of the actual dynamically loadable object file residing in
- the directory given as <c>Path</c>, but <em>without</em> the
+ the directory given as <c><anno>Path</anno></c>, but <em>without</em> the
extension (i.e. <c>.so</c>). The driver name provided in
the driver initialization routine must correspond with the
filename, in much the same way as erlang module names
@@ -328,14 +316,14 @@
<p>If the driver has been previously unloaded, but is still
present due to open ports against it, a call to
<c>load/2</c> will stop the unloading and keep the driver
- (as long as the <c>Path</c> is the same) and <c>ok</c> is
+ (as long as the <c><anno>Path</anno></c> is the same) and <c>ok</c> is
returned. If one actually wants the object code to be
reloaded, one uses <seealso marker="#reload/2">reload/2</seealso> or the low-level
interface <seealso marker="#try_load/3">try_load/3</seealso>
instead. Please refer to the description of <seealso marker="#scenarios">different scenarios</seealso> for
loading/unloading in the introduction.</p>
<p>If more than one process tries to load an already loaded
- driver withe the same <c>Path</c>, or if the same process
+ driver withe the same <c><anno>Path</anno></c>, or if the same process
tries to load it several times, the function will return
<c>ok</c>. The emulator will keep track of the
<c>load/2</c> calls, so that a corresponding number of
@@ -349,16 +337,16 @@
several drivers with the same name but with different
<c>Path</c> parameters.</p>
<note>
- <p>Note especially that the <c>Path</c> is interpreted
+ <p>Note especially that the <c><anno>Path</anno></c> is interpreted
literally, so that all loaders of the same driver needs to
- give the same <em>literal</em><c>Path</c> string, even
+ give the same <em>literal</em><c><anno>Path</anno></c> string, even
though different paths might point out the same directory
in the filesystem (due to use of relative paths and
links).</p>
</note>
<p>On success, the function returns <c>ok</c>. On
- failure, the return value is <c>{error,ErrorDesc}</c>,
- where <c>ErrorDesc</c> is an opaque term to be
+ failure, the return value is <c>{error,<anno>ErrorDesc</anno>}</c>,
+ where <c><anno>ErrorDesc</anno></c> is an opaque term to be
translated into human readable form by the <seealso marker="#format_error/1">format_error/1</seealso>
function.</p>
<p>For more control over the error handling, again use the
@@ -369,20 +357,16 @@
</desc>
</func>
<func>
- <name>load_driver(Path, Name) -> ok | {error, ErrorDesc}</name>
+ <name name="load_driver" arity="2"/>
<fsummary>Load a driver</fsummary>
- <type>
- <v>Path = Name = string() | atom()</v>
- <v>ErrorDesc = term()</v>
- </type>
<desc>
<p>Works essentially as <c>load/2</c>, but will load the driver
- with options other options. All ports that are using the
+ with other options. All ports that are using the
driver will get killed with the reason
<c>driver_unloaded</c> when the driver is to be unloaded.</p>
<p>The number of loads and unloads by different <seealso marker="#users">users</seealso> influence the actual loading
and unloading of a driver file. The port killing will
- therefore only happen when the <em>last</em><seealso marker="#users">user</seealso> unloads the driver, or the
+ therefore only happen when the <em>last</em> <seealso marker="#users">user</seealso> unloads the driver, or the
last process having loaded the driver exits.</p>
<p>This interface (or at least the name of the functions) is
kept for backward compatibility. Using <seealso marker="#try_load/3">try_load/3</seealso> with
@@ -551,16 +535,11 @@
</desc>
</func>
<func>
- <name>reload(Path, Name) -> ok | {error, ErrorDesc}</name>
+ <name name="reload" arity="2"/>
<fsummary>Replace a driver</fsummary>
- <type>
- <v>Path = Name = string() | atom()</v>
- <v>ErrorDesc = pending_process | OpaqueError</v>
- <v>OpaqueError = term()</v>
- </type>
<desc>
- <p>Reloads the driver named <c>Name</c> from a possibly
- different <c>Path</c> than was previously used. This
+ <p>Reloads the driver named <c><anno>Name</anno></c> from a possibly
+ different <c><anno>Path</anno></c> than was previously used. This
function is used in the code change <seealso marker="#scenarios">scenario</seealso> described in the
introduction.</p>
<p>If there are other <seealso marker="#users">users</seealso>
@@ -574,7 +553,7 @@
<p>If one wants to avoid hanging on open ports, one should use
the <seealso marker="#try_load/3">try_load/3</seealso>
function instead.</p>
- <p>The <c>Name</c> and <c>Path</c> parameters have exactly the
+ <p>The <c><anno>Name</anno></c> and <c><anno>Path</anno></c> parameters have exactly the
same meaning as when calling the plain <seealso marker="#load/2">load/2</seealso> function.</p>
<note>
<p>Avoid mixing
@@ -594,13 +573,8 @@
</desc>
</func>
<func>
- <name>reload_driver(Path, Name) -> ok | {error, ErrorDesc}</name>
+ <name name="reload_driver" arity="2"/>
<fsummary>Replace a driver</fsummary>
- <type>
- <v>Path = Name = string() | atom()</v>
- <v>ErrorDesc = pending_process | OpaqueError</v>
- <v>OpaqueError = term()</v>
- </type>
<desc>
<p>Works exactly as <seealso marker="#reload/2">reload/2</seealso>, but for drivers
loaded with the <seealso marker="#load_driver/2">load_driver/2</seealso> interface. </p>
@@ -1066,15 +1040,11 @@
</desc>
</func>
<func>
- <name>unload(Name) -> ok | {error, ErrorDesc}</name>
+ <name name="unload" arity="1"/>
<fsummary>Unload a driver</fsummary>
- <type>
- <v>Name = string() | atom()</v>
- <v>ErrorDesc = term()</v>
- </type>
<desc>
<p>Unloads, or at least dereferences the driver named
- <c>Name</c>. If the caller is the last <seealso marker="#users">user</seealso> of the driver, and there
+ <c><anno>Name</anno></c>. If the caller is the last <seealso marker="#users">user</seealso> of the driver, and there
are no more open ports using the driver, the driver will
actually get unloaded. In all other cases, actual unloading
will be delayed until all ports are closed and there are no
@@ -1084,7 +1054,7 @@
is no longer considered a user of the driver. For usage
scenarios, see the <seealso marker="#scenarios">description</seealso> in the beginning
of this document. </p>
- <p>The <c>ErrorDesc</c> returned is an opaque value to be
+ <p>The <c><anno>ErrorDesc</anno></c> returned is an opaque value to be
passed further on to the <seealso marker="#format_error/1">format_error/1</seealso>
function. For more control over the operation, use the
<seealso marker="#try_unload/2">try_unload/2</seealso>
@@ -1094,15 +1064,11 @@
</desc>
</func>
<func>
- <name>unload_driver(Name) -> ok | {error, ErrorDesc}</name>
+ <name name="unload_driver" arity="1"/>
<fsummary>Unload a driver</fsummary>
- <type>
- <v>Name = string() | atom()</v>
- <v>ErrorDesc = term()</v>
- </type>
<desc>
<p>Unloads, or at least dereferences the driver named
- <c>Name</c>. If the caller is the last <seealso marker="#users">user</seealso> of the driver, all
+ <c><anno>Name</anno></c>. If the caller is the last <seealso marker="#users">user</seealso> of the driver, all
remaining open ports using the driver will get killed with
the reason <c>driver_unloaded</c> and the driver will
eventually get unloaded.</p>
@@ -1112,7 +1078,7 @@
<seealso marker="#users">user</seealso>. For
usage scenarios, see the <seealso marker="#scenarios">description</seealso> in the beginning
of this document.</p>
- <p>The <c>ErrorDesc</c> returned is an opaque value to be
+ <p>The <c><anno>ErrorDesc</anno></c> returned is an opaque value to be
passed further on to the <seealso marker="#format_error/1">format_error/1</seealso>
function. For more control over the operation, use the
<seealso marker="#try_unload/2">try_unload/2</seealso>
@@ -1125,7 +1091,7 @@
<name>loaded_drivers() -> {ok, Drivers}</name>
<fsummary>List loaded drivers</fsummary>
<type>
- <v>Drivers = [Driver()]</v>
+ <v>Drivers = [Driver]</v>
<v>Driver = string()</v>
</type>
<desc>
@@ -1138,13 +1104,10 @@
</desc>
</func>
<func>
- <name>format_error(ErrorDesc) -> string()</name>
+ <name name="format_error" arity="1"/>
<fsummary>Format an error descriptor</fsummary>
- <type>
- <v>ErrorDesc -- see below</v>
- </type>
<desc>
- <p>Takes an <c>ErrorDesc</c> returned by load, unload or
+ <p>Takes an <c><anno>ErrorDesc</anno></c> returned by load, unload or
reload functions and returns a string which
describes the error or warning.</p>
<note>
diff --git a/lib/kernel/doc/src/error_handler.xml b/lib/kernel/doc/src/error_handler.xml
index 7f78322472..acbf9a2c6e 100644
--- a/lib/kernel/doc/src/error_handler.xml
+++ b/lib/kernel/doc/src/error_handler.xml
@@ -37,48 +37,44 @@
</description>
<funcs>
<func>
- <name>undefined_function(Module, Function, Args) -> term()</name>
+ <name name="undefined_function" arity="3"/>
<fsummary>Called when an undefined function is encountered</fsummary>
- <type>
- <v>Module = Function = atom()</v>
- <v>Args = [term()]</v>
- <d>A (possibly empty) list of arguments <c>Arg1,..,ArgN</c></d>
- </type>
+ <type_desc variable="Args">
+ A (possibly empty) list of arguments <c>Arg1,..,ArgN</c>
+ </type_desc>
<desc>
<p>This function is evaluated if a call is made to
- <c>Module:Function(Arg1,.., ArgN)</c> and
- <c>Module:Function/N</c> is undefined. Note that
+ <c><anno>Module</anno>:<anno>Function</anno>(Arg1,.., ArgN)</c> and
+ <c><anno>Module</anno>:<anno>Function</anno>/N</c> is undefined. Note that
<c>undefined_function/3</c> is evaluated inside the process
making the original call.</p>
- <p>If <c>Module</c> is interpreted, the interpreter is invoked
+ <p>If <c><anno>Module</anno></c> is interpreted, the interpreter is invoked
and the return value of the interpreted
- <c>Function(Arg1,.., ArgN)</c> call is returned.</p>
+ <c><anno>Function</anno>(Arg1,.., ArgN)</c> call is returned.</p>
<p>Otherwise, it returns, if possible, the value of
- <c>apply(Module, Function, Args)</c> after an attempt has been
- made to autoload <c>Module</c>. If this is not possible, the
- call to <c>Module:Function(Arg1,.., ArgN)</c> fails with
+ <c>apply(<anno>Module</anno>, <anno>Function</anno>, <anno>Args</anno>)</c> after an attempt has been
+ made to autoload <c><anno>Module</anno></c>. If this is not possible, the
+ call to <c><anno>Module</anno>:<anno>Function</anno>(Arg1,.., ArgN)</c> fails with
exit reason <c>undef</c>.</p>
</desc>
</func>
<func>
- <name>undefined_lambda(Module, Fun, Args) -> term()</name>
+ <name name="undefined_lambda" arity="3"/>
<fsummary>Called when an undefined lambda (fun) is encountered</fsummary>
- <type>
- <v>Module = Function = atom()</v>
- <v>Args = [term()]</v>
- <d>A (possibly empty) list of arguments <c>Arg1,..,ArgN</c></d>
- </type>
+ <type_desc variable="Args">
+ A (possibly empty) list of arguments <c>Arg1,..,ArgN</c>
+ </type_desc>
<desc>
<p>This function is evaluated if a call is made to
- <c>Fun(Arg1,.., ArgN)</c> when the module defining the fun is
+ <c><anno>Fun</anno>(Arg1,.., ArgN)</c> when the module defining the fun is
not loaded. The function is evaluated inside the process
making the original call.</p>
- <p>If <c>Module</c> is interpreted, the interpreter is invoked
+ <p>If <c><anno>Module</anno></c> is interpreted, the interpreter is invoked
and the return value of the interpreted
- <c>Fun(Arg1,.., ArgN)</c> call is returned.</p>
+ <c><anno>Fun</anno>(Arg1,.., ArgN)</c> call is returned.</p>
<p>Otherwise, it returns, if possible, the value of
- <c>apply(Fun, Args)</c> after an attempt has been made to
- autoload <c>Module</c>. If this is not possible, the call
+ <c>apply(<anno>Fun</anno>, <anno>Args</anno>)</c> after an attempt has been made to
+ autoload <c><anno>Module</anno></c>. If this is not possible, the call
fails with exit reason <c>undef</c>.</p>
</desc>
</func>
diff --git a/lib/kernel/doc/src/error_logger.xml b/lib/kernel/doc/src/error_logger.xml
index e107d9b746..2d95f96ac7 100644
--- a/lib/kernel/doc/src/error_logger.xml
+++ b/lib/kernel/doc/src/error_logger.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2009</year>
+ <year>1996</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -65,19 +65,20 @@
be tagged as warnings or info. Tagging them as warnings may
require rewriting existing user defined event handlers.</p>
</description>
+ <datatypes>
+ <datatype>
+ <name name="report"/>
+ </datatype>
+ </datatypes>
<funcs>
<func>
- <name>error_msg(Format) -> ok</name>
- <name>error_msg(Format, Data) -> ok</name>
- <name>format(Format, Data) -> ok</name>
+ <name name="error_msg" arity="1"/>
+ <name name="error_msg" arity="2"/>
+ <name name="format" arity="2"/>
<fsummary>Send an standard error event to the error logger</fsummary>
- <type>
- <v>Format = string()</v>
- <v>Data = [term()]</v>
- </type>
<desc>
<p>Sends a standard error event to the error logger.
- The <c>Format</c> and <c>Data</c> arguments are the same as
+ The <c><anno>Format</anno></c> and <c><anno>Data</anno></c> arguments are the same as
the arguments of <c>io:format/2</c>. The event is handled by
the standard event handler.</p>
<pre>
@@ -94,12 +95,8 @@ ok</pre>
</desc>
</func>
<func>
- <name>error_report(Report) -> ok</name>
+ <name name="error_report" arity="1"/>
<fsummary>Send a standard error report event to the error logger</fsummary>
- <type>
- <v>Report = [{Tag, Data} | term()] | string() | term()</v>
- <v>&nbsp;Tag = Data = term()</v>
- </type>
<desc>
<p>Sends a standard error report event to the error logger.
The event is handled by the standard event handler.</p>
@@ -119,18 +116,13 @@ ok</pre>
</desc>
</func>
<func>
- <name>error_report(Type, Report) -> ok</name>
+ <name name="error_report" arity="2"/>
<fsummary>Send a user defined error report event to the error logger</fsummary>
- <type>
- <v>Type = term()</v>
- <v>Report = [{Tag, Data} | term()] | string() | term()</v>
- <v>&nbsp;Tag = Data = term()</v>
- </type>
<desc>
<p>Sends a user defined error report event to the error logger.
An event handler to handle the event is supposed to have been
added. The event is ignored by the standard event handler.</p>
- <p>It is recommended that <c>Report</c> follows the same
+ <p>It is recommended that <c><anno>Report</anno></c> follows the same
structure as for <c>error_report/1</c>.</p>
</desc>
</func>
@@ -174,16 +166,12 @@ ok</pre>
</desc>
</func>
<func>
- <name>warning_msg(Format) -> ok</name>
- <name>warning_msg(Format, Data) -> ok</name>
+ <name name="warning_msg" arity="1"/>
+ <name name="warning_msg" arity="2"/>
<fsummary>Send a standard warning event to the error logger</fsummary>
- <type>
- <v>Format = string()</v>
- <v>Data = [term()]</v>
- </type>
<desc>
<p>Sends a standard warning event to the error logger.
- The <c>Format</c> and <c>Data</c> arguments are the same as
+ The <c><anno>Format</anno></c> and <c><anno>Data</anno></c> arguments are the same as
the arguments of <c>io:format/2</c>. The event is handled by
the standard event handler. It is tagged either as an error,
warning or info, see
@@ -196,12 +184,8 @@ ok</pre>
</desc>
</func>
<func>
- <name>warning_report(Report) -> ok</name>
+ <name name="warning_report" arity="1"/>
<fsummary>Send a standard warning report event to the error logger</fsummary>
- <type>
- <v>Report = [{Tag, Data} | term()] | string() | term()</v>
- <v>&nbsp;Tag = Data = term()</v>
- </type>
<desc>
<p>Sends a standard warning report event to the error logger.
The event is handled by the standard event handler. It is
@@ -210,13 +194,8 @@ ok</pre>
</desc>
</func>
<func>
- <name>warning_report(Type, Report) -> ok</name>
+ <name name="warning_report" arity="2"/>
<fsummary>Send a user defined warning report event to the error logger</fsummary>
- <type>
- <v>Type = term()</v>
- <v>Report = [{Tag, Data} | term()] | string() | term()</v>
- <v>&nbsp;Tag = Data = term()</v>
- </type>
<desc>
<p>Sends a user defined warning report event to the error
logger. An event handler to handle the event is supposed to
@@ -227,16 +206,12 @@ ok</pre>
</desc>
</func>
<func>
- <name>info_msg(Format) -> ok</name>
- <name>info_msg(Format, Data) -> ok</name>
+ <name name="info_msg" arity="1"/>
+ <name name="info_msg" arity="2"/>
<fsummary>Send a standard information event to the error logger</fsummary>
- <type>
- <v>Format = string()</v>
- <v>Data = [term()]</v>
- </type>
<desc>
<p>Sends a standard information event to the error logger.
- The <c>Format</c> and <c>Data</c> arguments are the same as
+ The <c><anno>Format</anno></c> and <c><anno>Data</anno></c> arguments are the same as
the arguments of <c>io:format/2</c>. The event is handled by
the standard event handler.</p>
<pre>
@@ -253,12 +228,8 @@ ok</pre>
</desc>
</func>
<func>
- <name>info_report(Report) -> ok</name>
+ <name name="info_report" arity="1"/>
<fsummary>Send a standard information report event to the error logger</fsummary>
- <type>
- <v>Report = [{Tag, Data} | term()] | string() | term()</v>
- <v>&nbsp;Tag = Data = term()</v>
- </type>
<desc>
<p>Sends a standard information report event to the error
logger. The event is handled by the standard event handler.</p>
@@ -278,63 +249,49 @@ ok</pre>
</desc>
</func>
<func>
- <name>info_report(Type, Report) -> ok</name>
+ <name name="info_report" arity="2"/>
<fsummary>Send a user defined information report event to the error logger</fsummary>
- <type>
- <v>Type = term()</v>
- <v>Report = [{Tag, Data} | term()] | string() | term()</v>
- <v>&nbsp;Tag = Data = term()</v>
- </type>
<desc>
<p>Sends a user defined information report event to the error
logger. An event handler to handle the event is supposed to
have been added. The event is ignored by the standard event
handler.</p>
- <p>It is recommended that <c>Report</c> follows the same
+ <p>It is recommended that <c><anno>Report</anno></c> follows the same
structure as for <c>info_report/1</c>.</p>
</desc>
</func>
<func>
- <name>add_report_handler(Handler) -> Result</name>
- <name>add_report_handler(Handler, Args) -> Result</name>
+ <name name="add_report_handler" arity="1"/>
+ <name name="add_report_handler" arity="2"/>
<fsummary>Add an event handler to the error logger</fsummary>
- <type>
- <v>Handler, Args, Result -- see gen_event:add_handler/3</v>
- </type>
<desc>
<p>Adds a new event handler to the error logger. The event
handler must be implemented as a <c>gen_event</c> callback
module, see
<seealso marker="stdlib:gen_event">gen_event(3)</seealso>.</p>
- <p><c>Handler</c> is typically the name of the callback module
- and <c>Args</c> is an optional term (defaults to []) passed
- to the initialization callback function <c>Module:init/1</c>.
+ <p><c><anno>Handler</anno></c> is typically the name of the callback module
+ and <c><anno>Args</anno></c> is an optional term (defaults to []) passed
+ to the initialization callback function <c><anno>Handler</anno>:init/1</c>.
The function returns <c>ok</c> if successful.</p>
<p>The event handler must be able to handle the
<seealso marker="#events">events</seealso> described below.</p>
</desc>
</func>
<func>
- <name>delete_report_handler(Handler) -> Result</name>
+ <name name="delete_report_handler" arity="1"/>
<fsummary>Delete an event handler from the error logger</fsummary>
- <type>
- <v>Handler, Result -- see gen_event:delete_handler/3</v>
- </type>
<desc>
<p>Deletes an event handler from the error logger by calling
- <c>gen_event:delete_handler(error_logger, Handler, [])</c>,
+ <c>gen_event:delete_handler(error_logger, <anno>Handler</anno>, [])</c>,
see <seealso marker="stdlib:gen_event">gen_event(3)</seealso>.</p>
</desc>
</func>
<func>
- <name>tty(Flag) -> ok</name>
+ <name name="tty" arity="1"/>
<fsummary>Enable or disable printouts to the tty</fsummary>
- <type>
- <v>Flag = bool()</v>
- </type>
<desc>
- <p>Enables (<c>Flag == true</c>) or disables
- (<c>Flag == false</c>) printout of standard events to the tty.</p>
+ <p>Enables (<c><anno>Flag</anno> == true</c>) or disables
+ (<c><anno>Flag</anno> == false</c>) printout of standard events to the tty.</p>
<p>This is done by adding or deleting the standard event handler
for output to tty, thus calling this function overrides
the value of the Kernel <c>error_logger</c> configuration
@@ -342,13 +299,15 @@ ok</pre>
</desc>
</func>
<func>
- <name>logfile(Request) -> ok | Filename | {error, What}</name>
+ <name name="logfile" arity="1" clause_i="1"/>
+ <name name="logfile" arity="1" clause_i="2"/>
+ <name name="logfile" arity="1" clause_i="3"/>
+ <type variable="Filename"/>
+ <type variable="OpenReason" name_i="1"/>
+ <type variable="CloseReason" name_i="2"/>
+ <type variable="FilenameReason" name_i="3"/>
+ <type name="open_error"/>
<fsummary>Enable or disable error printouts to a file</fsummary>
- <type>
- <v>Request = {open, Filename} | close | filename</v>
- <v>&nbsp;Filename = atom() | string()</v>
- <v>What = allready_have_logfile | no_log_file | term()</v>
- </type>
<desc>
<p>Enables or disables printout of standard events to a file.</p>
<p>This is done by adding or deleting the standard event handler
@@ -361,22 +320,22 @@ ok</pre>
There can only be one active log file at a time.</p>
<p><c>Request</c> is one of:</p>
<taglist>
- <tag><c>{open, Filename}</c></tag>
+ <tag><c>{open, <anno>Filename</anno>}</c></tag>
<item>
- <p>Opens the log file <c>Filename</c>. Returns <c>ok</c> if
+ <p>Opens the log file <c><anno>Filename</anno></c>. Returns <c>ok</c> if
successful, or <c>{error, allready_have_logfile}</c> if
logging to file is already enabled, or an error tuple if
- another error occurred. For example, if <c>Filename</c>
+ another error occurred. For example, if <c><anno>Filename</anno></c>
could not be opened.</p>
</item>
<tag><c>close</c></tag>
<item>
<p>Closes the current log file. Returns <c>ok</c>, or
- <c>{error, What}</c>.</p>
+ <c>{error, module_not_found}</c>.</p>
</item>
<tag><c>filename</c></tag>
<item>
- <p>Returns the name of the log file <c>Filename</c>, or
+ <p>Returns the name of the log file <c><anno>Filename</anno></c>, or
<c>{error, no_log_file}</c> if logging to file is not
enabled.</p>
</item>
diff --git a/lib/kernel/doc/src/file.xml b/lib/kernel/doc/src/file.xml
index 36fce464c5..e0feaf6ee7 100644
--- a/lib/kernel/doc/src/file.xml
+++ b/lib/kernel/doc/src/file.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2010</year>
+ <year>1996</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -93,47 +93,76 @@
is UTF-8...</p>
</description>
- <section>
- <title>DATA TYPES</title>
- <code type="none">
-iodata() = iolist() | binary()
- iolist() = [char() | binary() | iolist()]
-
-io_device()
- as returned by file:open/2, a process handling IO protocols
-
-name() = string() | atom() | DeepList | RawFilename
- DeepList = [char() | atom() | DeepList]
- RawFilename = binary()
- If VM is in unicode filename mode, string() and char() are allowed to be > 255.
- RawFilename is a filename not subject to Unicode translation, meaning that it
- can contain characters not conforming to the Unicode encoding expected from the
- filesystem (i.e. non-UTF-8 characters although the VM is started in Unicode
- filename mode).
-
-posix()
- an atom which is named from the POSIX error codes used in
- Unix, and in the runtime libraries of most C compilers
-
-ext_posix() = posix() | badarg
+ <datatypes>
+ <datatype>
+ <name name="bindings"/>
+ </datatype>
+ <datatype>
+ <name name="deep_list"/>
+ </datatype>
+ <datatype>
+ <name name="fd"/>
+ </datatype>
+ <datatype>
+ <name name="filename"/>
+ </datatype>
+ <datatype>
+ <name name="io_device"/>
+ <desc>
+ <p>As returned by
+ <seealso marker="#open/2">file:open/2</seealso>,
+ a process handling IO protocols.</p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="name"/>
+ <desc>
+ <p>If VM is in Unicode filename mode, <c>string()</c> and <c>char()</c>
+ are allowed to be > 255.
+ <c><anno>RawFilename</anno></c> is a filename not subject to
+ Unicode translation,
+ meaning that it can contain characters not conforming to
+ the Unicode encoding expected from the filesystem
+ (i.e. non-UTF-8 characters although the VM is started
+ in Unicode filename mode).
+ </p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="posix"/>
+ <desc>
+ <p>An atom which is named from the POSIX error codes used in
+ Unix, and in the runtime libraries of most C compilers.</p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="date"/>
+ </datatype>
+ <datatype>
+ <name name="time"/>
+ </datatype>
+ <datatype>
+ <name name="date_time"/>
+ <desc>
+ <p>Must denote a valid date and time.</p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="file_info"/>
+ </datatype>
+ <datatype>
+ <name name="location"/>
+ </datatype>
+ <datatype>
+ <name name="mode"/>
+ </datatype>
+ </datatypes>
-time() = {{Year, Month, Day}, {Hour, Minute, Second}}
- Year = Month = Day = Hour = Minute = Second = int()
- Must denote a valid date and time</code>
- </section>
<funcs>
<func>
- <name>advise(IoDevice, Offset, Length, Advise) -> ok | {error, Reason}</name>
+ <name name="advise" arity="4"/>
<fsummary>Predeclare an access pattern for file data</fsummary>
- <type>
- <v>IoDevice = io_device()</v>
- <v>Offset = int()</v>
- <v>Length = int()</v>
- <v>Advise = posix_file_advise()</v>
- <v>posix_file_advise() = normal | sequential | random | no_reuse
- | will_need | dont_need</v>
- <v>Reason = ext_posix()</v>
- </type>
+ <type name="posix_file_advise"/>
<desc>
<p><c>advise/4</c> can be used to announce an intention to access file
data in a specific pattern in the future, thus allowing the
@@ -142,93 +171,58 @@ time() = {{Year, Month, Day}, {Hour, Minute, Second}}
</desc>
</func>
<func>
- <name>change_group(Filename, Gid) -> ok | {error, Reason}</name>
+ <name name="change_group" arity="2"/>
<fsummary>Change group of a file</fsummary>
- <type>
- <v>Filename = name()</v>
- <v>Gid = int()</v>
- <v>Reason = ext_posix()</v>
- </type>
<desc>
<p>Changes group of a file. See
<seealso marker="#write_file_info/2">write_file_info/2</seealso>.</p>
</desc>
</func>
<func>
- <name>change_mode(Filename, Mode) -> ok | {error, Reason}</name>
+ <name name="change_mode" arity="2"/>
<fsummary>Change permissions of a file</fsummary>
- <type>
- <v>Filename = name()</v>
- <v>Mode = int()</v>
- <v>Reason = ext_posix()</v>
- </type>
<desc>
<p>Changes permissions of a file. See
<seealso marker="#write_file_info/2">write_file_info/2</seealso>.</p>
</desc>
</func>
<func>
- <name>change_owner(Filename, Uid) -> ok | {error, Reason}</name>
+ <name name="change_owner" arity="2"/>
<fsummary>Change owner of a file</fsummary>
- <type>
- <v>Filename = name()</v>
- <v>Uid = int()</v>
- <v>Reason = ext_posix()</v>
- </type>
<desc>
<p>Changes owner of a file. See
<seealso marker="#write_file_info/2">write_file_info/2</seealso>.</p>
</desc>
</func>
<func>
- <name>change_owner(Filename, Uid, Gid) -> ok | {error, Reason}</name>
+ <name name="change_owner" arity="3"/>
<fsummary>Change owner and group of a file</fsummary>
- <type>
- <v>Filename = name()</v>
- <v>Uid = int()</v>
- <v>Gid = int()</v>
- <v>Reason = ext_posix()</v>
- </type>
<desc>
<p>Changes owner and group of a file. See
<seealso marker="#write_file_info/2">write_file_info/2</seealso>.</p>
</desc>
</func>
<func>
- <name>change_time(Filename, Mtime) -> ok | {error, Reason}</name>
+ <name name="change_time" arity="2"/>
<fsummary>Change the modification time of a file</fsummary>
- <type>
- <v>Filename = name()</v>
- <v>Mtime = time()</v>
- <v>Reason = ext_posix()</v>
- </type>
<desc>
<p>Changes the modification and access times of a file. See
<seealso marker="#write_file_info/2">write_file_info/2</seealso>.</p>
</desc>
</func>
<func>
- <name>change_time(Filename, Mtime, Atime) -> ok | {error, Reason}</name>
+ <name name="change_time" arity="3"/>
<fsummary>Change the modification and last access time of a file</fsummary>
- <type>
- <v>Filename = name()</v>
- <v>Mtime = Atime = time()</v>
- <v>Reason = ext_posix()</v>
- </type>
<desc>
<p>Changes the modification and last access times of a file. See
<seealso marker="#write_file_info/2">write_file_info/2</seealso>.</p>
</desc>
</func>
<func>
- <name>close(IoDevice) -> ok | {error, Reason}</name>
+ <name name="close" arity="1"/>
<fsummary>Close a file</fsummary>
- <type>
- <v>IoDevice = io_device()</v>
- <v>Reason = ext_posix() | terminated</v>
- </type>
<desc>
- <p>Closes the file referenced by <c>IoDevice</c>. It mostly
+ <p>Closes the file referenced by <c><anno>IoDevice</anno></c>. It mostly
returns <c>ok</c>, expect for some severe errors such as out
of memory.</p>
<p>Note that if the option <c>delayed_write</c> was
@@ -238,20 +232,13 @@ time() = {{Year, Month, Day}, {Hour, Minute, Second}}
</desc>
</func>
<func>
- <name>consult(Filename) -> {ok, Terms} | {error, Reason}</name>
+ <name name="consult" arity="1"/>
<fsummary>Read Erlang terms from a file</fsummary>
- <type>
- <v>Filename = name()</v>
- <v>Terms = [term()]</v>
- <v>Reason = ext_posix() | terminated | system_limit
- | {Line, Mod, Term}</v>
- <v>&nbsp;Line, Mod, Term -- see below</v>
- </type>
<desc>
- <p>Reads Erlang terms, separated by '.', from <c>Filename</c>.
- Returns one of the following:</p>
+ <p>Reads Erlang terms, separated by '.', from
+ <c><anno>Filename</anno></c>. Returns one of the following:</p>
<taglist>
- <tag><c>{ok, Terms}</c></tag>
+ <tag><c>{ok, <anno>Terms</anno>}</c></tag>
<item>
<p>The file was successfully read.</p>
</item>
@@ -261,7 +248,8 @@ time() = {{Year, Month, Day}, {Hour, Minute, Second}}
See <seealso marker="#open/2">open/2</seealso> for a list
of typical error codes.</p>
</item>
- <tag><c>{error, {Line, Mod, Term}}</c></tag>
+ <tag><c>{error, {<anno>Line</anno>, <anno>Mod</anno>,
+ <anno>Term</anno>}}</c></tag>
<item>
<p>An error occurred when interpreting the Erlang terms in
the file. Use <c>format_error/1</c> to convert
@@ -279,53 +267,46 @@ f.txt: {person, "kalle", 25}.
</desc>
</func>
<func>
- <name>copy(Source, Destination) -></name>
- <name>copy(Source, Destination, ByteCount) -> {ok, BytesCopied} | {error, Reason}</name>
+ <name name="copy" arity="2"/>
+ <name name="copy" arity="3"/>
<fsummary>Copy file contents</fsummary>
- <type>
- <v>Source = Destination = io_device() | Filename | {Filename, Modes}</v>
- <v>&nbsp;Filename = name()</v>
- <v>&nbsp;Modes = [Mode] -- see open/2</v>
- <v>ByteCount = int() >= 0 | infinity</v>
- <v>BytesCopied = int()</v>
- </type>
<desc>
- <p>Copies <c>ByteCount</c> bytes from <c>Source</c> to
- <c>Destination</c>. <c>Source</c> and <c>Destination</c> refer
+ <p>Copies <c><anno>ByteCount</anno></c> bytes from
+ <c><anno>Source</anno></c> to <c><anno>Destination</anno></c>.
+ <c><anno>Source</anno></c> and <c><anno>Destination</anno></c> refer
to either filenames or IO devices from e.g. <c>open/2</c>.
- <c>ByteCount</c> defaults <c>infinity</c>, denoting an
+ <c><anno>ByteCount</anno></c> defaults to <c>infinity</c>, denoting an
infinite number of bytes.</p>
- <p>The argument <c>Modes</c> is a list of possible modes, see
- <seealso marker="#open/2">open/2</seealso>, and defaults to
+ <p>The argument <c><anno>Modes</anno></c> is a list of possible modes,
+ see <seealso marker="#open/2">open/2</seealso>, and defaults to
[].</p>
- <p>If both <c>Source</c> and <c>Destination</c> refer to
+ <p>If both <c><anno>Source</anno></c> and
+ <c><anno>Destination</anno></c> refer to
filenames, the files are opened with <c>[read, binary]</c>
and <c>[write, binary]</c> prepended to their mode lists,
respectively, to optimize the copy.</p>
- <p>If <c>Source</c> refers to a filename, it is opened with
+ <p>If <c><anno>Source</anno></c> refers to a filename, it is opened with
<c>read</c> mode prepended to the mode list before the copy,
and closed when done.</p>
- <p>If <c>Destination</c> refers to a filename, it is opened
+ <p>If <c><anno>Destination</anno></c> refers to a filename, it is opened
with <c>write</c> mode prepended to the mode list before
the copy, and closed when done.</p>
- <p>Returns <c>{ok, BytesCopied}</c> where <c>BytesCopied</c> is
+ <p>Returns <c>{ok, <anno>BytesCopied</anno>}</c> where
+ <c><anno>BytesCopied</anno></c> is
the number of bytes that actually was copied, which may be
- less than <c>ByteCount</c> if end of file was encountered on
- the source. If the operation fails, <c>{error, Reason}</c> is
- returned.</p>
+ less than <c><anno>ByteCount</anno></c> if end of file was
+ encountered on the source. If the operation fails,
+ <c>{error, <anno>Reason</anno>}</c> is returned.</p>
<p>Typical error reasons: As for <c>open/2</c> if a file had to
be opened, and as for <c>read/2</c> and <c>write/2</c>.</p>
</desc>
</func>
<func>
- <name>del_dir(Dir) -> ok | {error, Reason}</name>
+ <name name="del_dir" arity="1"/>
<fsummary>Delete a directory</fsummary>
- <type>
- <v>Dir = name()</v>
- <v>Reason = ext_posix()</v>
- </type>
<desc>
- <p>Tries to delete the directory <c>Dir</c>. The directory must
+ <p>Tries to delete the directory <c><anno>Dir</anno></c>.
+ The directory must
be empty before it can be deleted. Returns <c>ok</c> if
successful.</p>
<p>Typical error reasons are:</p>
@@ -333,7 +314,7 @@ f.txt: {person, "kalle", 25}.
<tag><c>eacces</c></tag>
<item>
<p>Missing search or write permissions for the parent
- directories of <c>Dir</c>.</p>
+ directories of <c><anno>Dir</anno></c>.</p>
</item>
<tag><c>eexist</c></tag>
<item>
@@ -345,8 +326,8 @@ f.txt: {person, "kalle", 25}.
</item>
<tag><c>enotdir</c></tag>
<item>
- <p>A component of <c>Dir</c> is not a directory. On some
- platforms, <c>enoent</c> is returned instead.</p>
+ <p>A component of <c><anno>Dir</anno></c> is not a directory.
+ On some platforms, <c>enoent</c> is returned instead.</p>
</item>
<tag><c>einval</c></tag>
<item>
@@ -357,15 +338,11 @@ f.txt: {person, "kalle", 25}.
</desc>
</func>
<func>
- <name>delete(Filename) -> ok | {error, Reason}</name>
+ <name name="delete" arity="1"/>
<fsummary>Delete a file</fsummary>
- <type>
- <v>Filename = name()</v>
- <v>Reason = ext_posix()</v>
- </type>
<desc>
- <p>Tries to delete the file <c>Filename</c>. Returns <c>ok</c>
- if successful.</p>
+ <p>Tries to delete the file <c><anno>Filename</anno></c>.
+ Returns <c>ok</c> if successful.</p>
<p>Typical error reasons are:</p>
<taglist>
<tag><c>enoent</c></tag>
@@ -387,30 +364,25 @@ f.txt: {person, "kalle", 25}.
</item>
<tag><c>einval</c></tag>
<item>
- <p><c>Filename</c> had an improper type, such as tuple.</p>
+ <p><c><anno>Filename</anno></c> had an improper type, such as tuple.</p>
</item>
</taglist>
<warning>
- <p>In a future release, a bad type for the <c>Filename</c>
- argument will probably generate an exception.</p>
+ <p>In a future release, a bad type for the
+ <c><anno>Filename</anno></c> argument will probably generate
+ an exception.</p>
<p></p>
</warning>
</desc>
</func>
<func>
- <name>eval(Filename) -> ok | {error, Reason}</name>
+ <name name="eval" arity="1"/>
<fsummary>Evaluate Erlang expressions in a file</fsummary>
- <type>
- <v>Filename = name()</v>
- <v>Reason = ext_posix() | terminated | system_limit
- | {Line, Mod, Term}</v>
- <v>&nbsp;Line, Mod, Term -- see below</v>
- </type>
<desc>
<p>Reads and evaluates Erlang expressions, separated by '.' (or
',', a sequence of expressions is also an expression), from
- <c>Filename</c>. The actual result of the evaluation is not
- returned; any expression sequence in the file must be there
+ <c><anno>Filename</anno></c>. The actual result of the evaluation
+ is not returned; any expression sequence in the file must be there
for its side effect. Returns one of the following:</p>
<taglist>
<tag><c>ok</c></tag>
@@ -422,7 +394,8 @@ f.txt: {person, "kalle", 25}.
<p>An error occurred when opening the file or reading it.
See <c>open/2</c> for a list of typical error codes.</p>
</item>
- <tag><c>{error, {Line, Mod, Term}}</c></tag>
+ <tag><c>{error, {<anno>Line</anno>, <anno>Mod</anno>,
+ <anno>Term</anno>}}</c></tag>
<item>
<p>An error occurred when interpreting the Erlang
expressions in the file. Use <c>format_error/1</c> to
@@ -433,18 +406,11 @@ f.txt: {person, "kalle", 25}.
</desc>
</func>
<func>
- <name>eval(Filename, Bindings) -> ok | {error, Reason}</name>
+ <name name="eval" arity="2"/>
<fsummary>Evaluate Erlang expressions in a file</fsummary>
- <type>
- <v>Filename = name()</v>
- <v>Bindings -- see erl_eval(3)</v>
- <v>Reason = ext_posix() | terminated | system_limit
- | {Line, Mod, Term}</v>
- <v>&nbsp;Line, Mod, Term -- see eval/1</v>
- </type>
<desc>
<p>The same as <c>eval/1</c> but the variable bindings
- <c>Bindings</c> are used in the evaluation. See
+ <c><anno>Bindings</anno></c> are used in the evaluation. See
<seealso marker="stdlib:erl_eval">erl_eval(3)</seealso> about
variable bindings.</p>
</desc>
@@ -458,27 +424,19 @@ f.txt: {person, "kalle", 25}.
</desc>
</func>
<func>
- <name>format_error(Reason) -> Chars</name>
+ <name name="format_error" arity="1"/>
<fsummary>Return a descriptive string for an error reason</fsummary>
- <type>
- <v>Reason = atom() | {Line, Mod, Term}</v>
- <v>&nbsp;Line, Mod, Term -- see eval/1</v>
- <v>Chars = [char() | Chars]</v>
- </type>
<desc>
<p>Given the error reason returned by any function in this
module, returns a descriptive string of the error in English.</p>
</desc>
</func>
<func>
- <name>get_cwd() -> {ok, Dir} | {error, Reason}</name>
+ <name name="get_cwd" arity="0"/>
<fsummary>Get the current working directory</fsummary>
- <type>
- <v>Dir = string()</v>
- <v>Reason = posix()</v>
- </type>
<desc>
- <p>Returns <c>{ok, Dir}</c>, where <c>Dir</c> is the current
+ <p>Returns <c>{ok, <anno>Dir</anno>}</c>, where <c><anno>Dir</anno></c>
+ is the current
working directory of the file server.</p>
<note>
<p>In rare circumstances, this function can fail on Unix.
@@ -496,17 +454,14 @@ f.txt: {person, "kalle", 25}.
</desc>
</func>
<func>
- <name>get_cwd(Drive) -> {ok, Dir} | {error, Reason}</name>
+ <name name="get_cwd" arity="1"/>
<fsummary>Get the current working directory for the drive specified</fsummary>
- <type>
- <v>Drive = string() -- see below</v>
- <v>Dir = string()</v>
- <v>Reason = ext_posix()</v>
- </type>
<desc>
- <p><c>Drive</c> should be of the form "<c>Letter</c><c>:</c>",
- for example "c:". Returns <c>{ok, Dir}</c> or
- <c>{error, Reason}</c>, where <c>Dir</c> is the current
+ <p><c><anno>Drive</anno></c> should be of the form
+ "<c>Letter</c><c>:</c>",
+ for example "c:". Returns <c>{ok, <anno>Dir</anno>}</c> or
+ <c>{error, <anno>Reason</anno>}</c>, where <c><anno>Dir</anno></c>
+ is the current
working directory of the drive specified.</p>
<p>This function returns <c>{error, enotsup}</c> on platforms
which have no concept of current drive (Unix, for example).</p>
@@ -514,7 +469,7 @@ f.txt: {person, "kalle", 25}.
<taglist>
<tag><c>enotsup</c></tag>
<item>
- <p>The operating system have no concept of drives.</p>
+ <p>The operating system has no concept of drives.</p>
</item>
<tag><c>eacces</c></tag>
<item>
@@ -522,32 +477,27 @@ f.txt: {person, "kalle", 25}.
</item>
<tag><c>einval</c></tag>
<item>
- <p>The format of <c>Drive</c> is invalid.</p>
+ <p>The format of <c><anno>Drive</anno></c> is invalid.</p>
</item>
</taglist>
</desc>
</func>
<func>
- <name>list_dir(Dir) -> {ok, Filenames} | {error, Reason}</name>
+ <name name="list_dir" arity="1"/>
<fsummary>List files in a directory</fsummary>
- <type>
- <v>Dir = name()</v>
- <v>Filenames = [Filename]</v>
- <v>&nbsp;Filename = string()</v>
- <v>Reason = ext_posix()</v>
- </type>
<desc>
<p>Lists all the files in a directory. Returns
- <c>{ok, Filenames}</c> if successful. Otherwise, it returns
- <c>{error, Reason}</c>. <c>Filenames</c> is a list of
+ <c>{ok, <anno>Filenames</anno>}</c> if successful.
+ Otherwise, it returns <c>{error, <anno>Reason</anno>}</c>.
+ <c><anno>Filenames</anno></c> is a list of
the names of all the files in the directory. The names are
not sorted.</p>
<p>Typical error reasons are:</p>
<taglist>
<tag><c>eacces</c></tag>
<item>
- <p>Missing search or write permissions for <c>Dir</c> or
- one of its parent directories.</p>
+ <p>Missing search or write permissions for <c><anno>Dir</anno></c>
+ or one of its parent directories.</p>
</item>
<tag><c>enoent</c></tag>
<item>
@@ -557,14 +507,10 @@ f.txt: {person, "kalle", 25}.
</desc>
</func>
<func>
- <name>make_dir(Dir) -> ok | {error, Reason}</name>
+ <name name="make_dir" arity="1"/>
<fsummary>Make a directory</fsummary>
- <type>
- <v>Dir = name()</v>
- <v>Reason = ext_posix()</v>
- </type>
<desc>
- <p>Tries to create the directory <c>Dir</c>. Missing parent
+ <p>Tries to create the directory <c><anno>Dir</anno></c>. Missing parent
directories are <em>not</em> created. Returns <c>ok</c> if
successful.</p>
<p>Typical error reasons are:</p>
@@ -572,15 +518,15 @@ f.txt: {person, "kalle", 25}.
<tag><c>eacces</c></tag>
<item>
<p>Missing search or write permissions for the parent
- directories of <c>Dir</c>.</p>
+ directories of <c><anno>Dir</anno></c>.</p>
</item>
<tag><c>eexist</c></tag>
<item>
- <p>There is already a file or directory named <c>Dir</c>.</p>
+ <p>There is already a file or directory named <c><anno>Dir</anno></c>.</p>
</item>
<tag><c>enoent</c></tag>
<item>
- <p>A component of <c>Dir</c> does not exist.</p>
+ <p>A component of <c><anno>Dir</anno></c> does not exist.</p>
</item>
<tag><c>enospc</c></tag>
<item>
@@ -588,35 +534,33 @@ f.txt: {person, "kalle", 25}.
</item>
<tag><c>enotdir</c></tag>
<item>
- <p>A component of <c>Dir</c> is not a directory. On some
- platforms, <c>enoent</c> is returned instead.</p>
+ <p>A component of <c><anno>Dir</anno></c> is not a directory.
+ On some platforms, <c>enoent</c> is returned instead.</p>
</item>
</taglist>
</desc>
</func>
<func>
- <name>make_link(Existing, New) -> ok | {error, Reason}</name>
+ <name name="make_link" arity="2"/>
<fsummary>Make a hard link to a file</fsummary>
- <type>
- <v>Existing = New = name()</v>
- <v>Reason = ext_posix()</v>
- </type>
<desc>
- <p>Makes a hard link from <c>Existing</c> to <c>New</c>, on
+ <p>Makes a hard link from <c><anno>Existing</anno></c> to
+ <c><anno>New</anno></c>, on
platforms that support links (Unix). This function returns
<c>ok</c> if the link was successfully created, or
- <c>{error, Reason}</c>. On platforms that do not support
+ <c>{error, <anno>Reason</anno>}</c>. On platforms that do not support
links, <c>{error,enotsup}</c> is returned.</p>
<p>Typical error reasons:</p>
<taglist>
<tag><c>eacces</c></tag>
<item>
<p>Missing read or write permissions for the parent
- directories of <c>Existing</c> or <c>New</c>.</p>
+ directories of <c><anno>Existing</anno></c> or
+ <c><anno>New</anno></c>.</p>
</item>
<tag><c>eexist</c></tag>
<item>
- <p><c>New</c> already exists.</p>
+ <p><c><anno>New</anno></c> already exists.</p>
</item>
<tag><c>enotsup</c></tag>
<item>
@@ -626,30 +570,28 @@ f.txt: {person, "kalle", 25}.
</desc>
</func>
<func>
- <name>make_symlink(Name1, Name2) -> ok | {error, Reason}</name>
+ <name name="make_symlink" arity="2"/>
<fsummary>Make a symbolic link to a file or directory</fsummary>
- <type>
- <v>Name1 = Name2 = name()</v>
- <v>Reason = ext_posix()</v>
- </type>
<desc>
- <p>This function creates a symbolic link <c>Name2</c> to
- the file or directory <c>Name1</c>, on platforms that support
- symbolic links (most Unix systems). <c>Name1</c> need not
+ <p>This function creates a symbolic link <c><anno>Name2</anno></c> to
+ the file or directory <c><anno>Name1</anno></c>, on platforms that
+ support
+ symbolic links (most Unix systems). <c><anno>Name1</anno></c> need not
exist. This function returns <c>ok</c> if the link was
- successfully created, or <c>{error, Reason}</c>. On platforms
+ successfully created, or <c>{error, <anno>Reason</anno>}</c>.
+ On platforms
that do not support symbolic links, <c>{error, enotsup}</c>
is returned.</p>
<p>Typical error reasons:</p>
<taglist>
<tag><c>eacces</c></tag>
<item>
- <p>Missing read or write permissions for the parent
- directories of <c>Name1</c> or <c>Name2</c>.</p>
+ <p>Missing read or write permissions for the parent directories
+ of <c><anno>Name1</anno></c> or <c><anno>Name2</anno></c>.</p>
</item>
<tag><c>eexist</c></tag>
<item>
- <p><c>Name2</c> already exists.</p>
+ <p><c><anno>Name2</anno></c> already exists.</p>
</item>
<tag><c>enotsup</c></tag>
<item>
@@ -668,22 +610,12 @@ f.txt: {person, "kalle", 25}.
</desc>
</func>
<func>
- <name>open(Filename, Modes) -> {ok, IoDevice} | {error, Reason}</name>
+ <name name="open" arity="2"/>
<fsummary>Open a file</fsummary>
- <type>
- <v>Filename = name()</v>
- <v>Modes = [Mode]</v>
- <v>&nbsp;Mode = read | write | append | exclusive | raw | binary | {delayed_write, Size, Delay} | delayed_write | {read_ahead, Size} | read_ahead | compressed | {encoding, Encoding}</v>
- <v>&nbsp;&nbsp;Size = Delay = int()</v>
- <v>&nbsp;&nbsp;Encoding = latin1 | unicode | utf8 | utf16 | {utf16, Endian} | utf32 | {utf32, Endian}</v>
- <v>&nbsp;&nbsp;&nbsp;&nbsp;Endian = big | little</v>
- <v>IoDevice = io_device()</v>
- <v>Reason = ext_posix() | system_limit</v>
- </type>
<desc>
- <p>Opens the file <c>Filename</c> in the mode determined by
- <c>Modes</c>, which may contain one or more of the following
- items:</p>
+ <p>Opens the file <c><anno>Filename</anno></c> in the mode determined
+ by <c><anno>Modes</anno></c>, which may contain one or more of the
+ following items:</p>
<taglist>
<tag><c>read</c></tag>
<item>
@@ -841,23 +773,23 @@ f.txt: {person, "kalle", 25}.
</taglist>
<p>Returns:</p>
<taglist>
- <tag><c>{ok, IoDevice}</c></tag>
+ <tag><c>{ok, <anno>IoDevice</anno>}</c></tag>
<item>
<p>The file has been opened in the requested mode.
- <c>IoDevice</c> is a reference to the file.</p>
+ <c><anno>IoDevice</anno></c> is a reference to the file.</p>
</item>
- <tag><c>{error, Reason}</c></tag>
+ <tag><c>{error, <anno>Reason</anno>}</c></tag>
<item>
<p>The file could not be opened.</p>
</item>
</taglist>
- <p><c>IoDevice</c> is really the pid of the process which
+ <p><c><anno>IoDevice</anno></c> is really the pid of the process which
handles the file. This process is linked to the process
which originally opened the file. If any process to which
- the <c>IoDevice</c> is linked terminates, the file will be
- closed and the process itself will be terminated.
- An <c>IoDevice</c> returned from this call can be used as an
- argument to the IO functions (see
+ the <c><anno>IoDevice</anno></c> is linked terminates, the file will
+ be closed and the process itself will be terminated.
+ An <c><anno>IoDevice</anno></c> returned from this call can be used
+ as an argument to the IO functions (see
<seealso marker="stdlib:io">io(3)</seealso>).</p>
<note>
<p>In previous versions of <c>file</c>, modes were given
@@ -897,34 +829,25 @@ f.txt: {person, "kalle", 25}.
</desc>
</func>
<func>
- <name>path_consult(Path, Filename) -> {ok, Terms, FullName} | {error, Reason}</name>
+ <name name="path_consult" arity="2"/>
<fsummary>Read Erlang terms from a file</fsummary>
- <type>
- <v>Path = [Dir]</v>
- <v>&nbsp;Dir = name()</v>
- <v>Filename = name()</v>
- <v>Terms = [term()]</v>
- <v>FullName = string()</v>
- <v>Reason = ext_posix() | terminated | system_limit
- | {Line, Mod, Term}</v>
- <v>&nbsp;Line, Mod, Term -- see below</v>
- </type>
<desc>
- <p>Searches the path <c>Path</c> (a list of directory names)
- until the file <c>Filename</c> is found. If <c>Filename</c>
- is an absolute filename, <c>Path</c> is ignored.
+ <p>Searches the path <c><anno>Path</anno></c> (a list of directory
+ names) until the file <c><anno>Filename</anno></c> is found.
+ If <c><anno>Filename</anno></c>
+ is an absolute filename, <c><anno>Path</anno></c> is ignored.
Then reads Erlang terms, separated by '.', from the file.
Returns one of the following:</p>
<taglist>
- <tag><c>{ok, Terms, FullName}</c></tag>
+ <tag><c>{ok, <anno>Terms</anno>, <anno>FullName</anno>}</c></tag>
<item>
- <p>The file was successfully read. <c>FullName</c> is
+ <p>The file was successfully read. <c><anno>FullName</anno></c> is
the full name of the file.</p>
</item>
<tag><c>{error, enoent}</c></tag>
<item>
<p>The file could not be found in any of the directories in
- <c>Path</c>.</p>
+ <c><anno>Path</anno></c>.</p>
</item>
<tag><c>{error, atom()}</c></tag>
<item>
@@ -932,7 +855,8 @@ f.txt: {person, "kalle", 25}.
See <seealso marker="#open/2">open/2</seealso> for a list
of typical error codes.</p>
</item>
- <tag><c>{error, {Line, Mod, Term}}</c></tag>
+ <tag><c>{error, {<anno>Line</anno>, <anno>Mod</anno>,
+ <anno>Term</anno>}}</c></tag>
<item>
<p>An error occurred when interpreting the Erlang terms in
the file. Use <c>format_error/1</c> to convert
@@ -943,36 +867,28 @@ f.txt: {person, "kalle", 25}.
</desc>
</func>
<func>
- <name>path_eval(Path, Filename) -> {ok, FullName} | {error, Reason}</name>
+ <name name="path_eval" arity="2"/>
<fsummary>Evaluate Erlang expressions in a file</fsummary>
- <type>
- <v>Path = [Dir]</v>
- <v>&nbsp;Dir = name()</v>
- <v>Filename = name()</v>
- <v>FullName = string()</v>
- <v>Reason = ext_posix() | terminated | system_limit
- | {Line, Mod, Term}</v>
- <v>&nbsp;Line, Mod, Term -- see below</v>
- </type>
<desc>
- <p>Searches the path <c>Path</c> (a list of directory names)
- until the file <c>Filename</c> is found. If <c>Filename</c>
- is an absolute file name, <c>Path</c> is ignored. Then reads
+ <p>Searches the path <c><anno>Path</anno></c> (a list of directory
+ names) until the file <c><anno>Filename</anno></c> is found.
+ If <c><anno>Filename</anno></c> is an absolute file name,
+ <c><anno>Path</anno></c> is ignored. Then reads
and evaluates Erlang expressions, separated by '.' (or ',', a
sequence of expressions is also an expression), from the file.
The actual result of evaluation is not returned; any
expression sequence in the file must be there for its side
effect. Returns one of the following:</p>
<taglist>
- <tag><c>{ok, FullName}</c></tag>
+ <tag><c>{ok, <anno>FullName</anno>}</c></tag>
<item>
- <p>The file was read and evaluated. <c>FullName</c> is
+ <p>The file was read and evaluated. <c><anno>FullName</anno></c> is
the full name of the file.</p>
</item>
<tag><c>{error, enoent}</c></tag>
<item>
<p>The file could not be found in any of the directories in
- <c>Path</c>.</p>
+ <c><anno>Path</anno></c>.</p>
</item>
<tag><c>{error, atom()}</c></tag>
<item>
@@ -980,7 +896,8 @@ f.txt: {person, "kalle", 25}.
See <seealso marker="#open/2">open/2</seealso> for a list
of typical error codes.</p>
</item>
- <tag><c>{error, {Line, Mod, Term}}</c></tag>
+ <tag><c>{error, {<anno>Line</anno>, <anno>Mod</anno>,
+ <anno>Term</anno>}}</c></tag>
<item>
<p>An error occurred when interpreting the Erlang
expressions in the file. Use <c>format_error/1</c> to
@@ -991,34 +908,26 @@ f.txt: {person, "kalle", 25}.
</desc>
</func>
<func>
- <name>path_open(Path, Filename, Modes) -> {ok, IoDevice, FullName} | {error, Reason}</name>
+ <name name="path_open" arity="3"/>
<fsummary>Open a file</fsummary>
- <type>
- <v>Path = [Dir]</v>
- <v>&nbsp;Dir = name()</v>
- <v>Filename = name()</v>
- <v>Modes = [Mode] -- see open/2</v>
- <v>IoDevice = io_device()</v>
- <v>FullName = string()</v>
- <v>Reason = ext_posix() | system_limit</v>
- </type>
<desc>
- <p>Searches the path <c>Path</c> (a list of directory names)
- until the file <c>Filename</c> is found. If <c>Filename</c>
- is an absolute file name, <c>Path</c> is ignored.
- Then opens the file in the mode determined by <c>Modes</c>.
+ <p>Searches the path <c><anno>Path</anno></c> (a list of directory
+ names) until the file <c><anno>Filename</anno></c> is found.
+ If <c><anno>Filename</anno></c>
+ is an absolute file name, <c><anno>Path</anno></c> is ignored.
+ Then opens the file in the mode determined by <c><anno>Modes</anno></c>.
Returns one of the following:</p>
<taglist>
- <tag><c>{ok, IoDevice, FullName}</c></tag>
+ <tag><c>{ok, <anno>IoDevice</anno>, <anno>FullName</anno>}</c></tag>
<item>
<p>The file has been opened in the requested mode.
- <c>IoDevice</c> is a reference to the file and
- <c>FullName</c> is the full name of the file.</p>
+ <c><anno>IoDevice</anno></c> is a reference to the file and
+ <c><anno>FullName</anno></c> is the full name of the file.</p>
</item>
<tag><c>{error, enoent}</c></tag>
<item>
<p>The file could not be found in any of the directories in
- <c>Path</c>.</p>
+ <c><anno>Path</anno></c>.</p>
</item>
<tag><c>{error, atom()}</c></tag>
<item>
@@ -1028,36 +937,27 @@ f.txt: {person, "kalle", 25}.
</desc>
</func>
<func>
- <name>path_script(Path, Filename) -> {ok, Value, FullName} | {error, Reason}</name>
+ <name name="path_script" arity="2"/>
<fsummary>Evaluate and return the value of Erlang expressions in a file</fsummary>
- <type>
- <v>Path = [Dir]</v>
- <v>&nbsp;Dir = name()</v>
- <v>Filename = name()</v>
- <v>Value = term()</v>
- <v>FullName = string()</v>
- <v>Reason = ext_posix() | terminated | system_limit
- | {Line, Mod, Term}</v>
- <v>&nbsp;Line, Mod, Term -- see below</v>
- </type>
<desc>
- <p>Searches the path <c>Path</c> (a list of directory names)
- until the file <c>Filename</c> is found. If <c>Filename</c>
- is an absolute file name, <c>Path</c> is ignored. Then reads
+ <p>Searches the path <c><anno>Path</anno></c> (a list of directory
+ names) until the file <c><anno>Filename</anno></c> is found.
+ If <c><anno>Filename</anno></c> is an absolute file name,
+ <c><anno>Path</anno></c> is ignored. Then reads
and evaluates Erlang expressions, separated by '.' (or ',', a
sequence of expressions is also an expression), from the file.
Returns one of the following:</p>
<taglist>
- <tag><c>{ok, Value, FullName}</c></tag>
+ <tag><c>{ok, <anno>Value</anno>, <anno>FullName</anno>}</c></tag>
<item>
- <p>The file was read and evaluated. <c>FullName</c> is
- the full name of the file and <c>Value</c> the value of
+ <p>The file was read and evaluated. <c><anno>FullName</anno></c> is
+ the full name of the file and <c><anno>Value</anno></c> the value of
the last expression.</p>
</item>
<tag><c>{error, enoent}</c></tag>
<item>
<p>The file could not be found in any of the directories in
- <c>Path</c>.</p>
+ <c><anno>Path</anno></c>.</p>
</item>
<tag><c>{error, atom()}</c></tag>
<item>
@@ -1065,7 +965,8 @@ f.txt: {person, "kalle", 25}.
See <seealso marker="#open/2">open/2</seealso> for a list
of typical error codes.</p>
</item>
- <tag><c>{error, {Line, Mod, Term}}</c></tag>
+ <tag><c>{error, {<anno>Line</anno>, <anno>Mod</anno>,
+ <anno>Term</anno>}}</c></tag>
<item>
<p>An error occurred when interpreting the Erlang
expressions in the file. Use <c>format_error/1</c> to
@@ -1076,42 +977,28 @@ f.txt: {person, "kalle", 25}.
</desc>
</func>
<func>
- <name>path_script(Path, Filename, Bindings) -> {ok, Value, FullName} | {error, Reason}</name>
+ <name name="path_script" arity="3"/>
<fsummary>Evaluate and return the value of Erlang expressions in a file</fsummary>
- <type>
- <v>Path = [Dir]</v>
- <v>&nbsp;Dir = name()</v>
- <v>Filename = name()</v>
- <v>Bindings -- see erl_eval(3)</v>
- <v>Value = term()</v>
- <v>FullName = string()</v>
- <v>Reason = posix() | terminated | system_limit
- | {Line, Mod, Term}</v>
- <v>&nbsp;Line, Mod, Term -- see path_script/2</v>
- </type>
<desc>
<p>The same as <c>path_script/2</c> but the variable bindings
- <c>Bindings</c> are used in the evaluation. See
+ <c><anno>Bindings</anno></c> are used in the evaluation. See
<seealso marker="stdlib:erl_eval">erl_eval(3)</seealso> about
variable bindings.</p>
</desc>
</func>
<func>
- <name>pid2name(Pid) -> string() | undefined</name>
+ <name name="pid2name" arity="1"/>
<fsummary>Return the name of the file handled by a pid</fsummary>
- <type>
- <v>Pid = pid()</v>
- </type>
<desc>
- <p>If <c>Pid</c> is an IO device, that is, a pid returned from
+ <p>If <c><anno>Pid</anno></c> is an IO device, that is, a pid returned from
<c>open/2</c>, this function returns the filename, or rather:</p>
<taglist>
- <tag><c>{ok, Filename}</c></tag>
+ <tag><c>{ok, <anno>Filename</anno>}</c></tag>
<item>
<p>If this node's file server is not a slave, the file was
opened by this node's file server, (this implies that
- <c>Pid</c> must be a local pid) and the file is not
- closed. <c>Filename</c> is the filename in flat string
+ <c><anno>Pid</anno></c> must be a local pid) and the file is not
+ closed. <c><anno>Filename</anno></c> is the filename in flat string
format.</p>
</item>
<tag><c>undefined</c></tag>
@@ -1125,21 +1012,15 @@ f.txt: {person, "kalle", 25}.
</desc>
</func>
<func>
- <name>position(IoDevice, Location) -> {ok, NewPosition} | {error, Reason}</name>
+ <name name="position" arity="2"/>
<fsummary>Set position in a file</fsummary>
- <type>
- <v>IoDevice = io_device()</v>
- <v>Location = Offset | {bof, Offset} | {cur, Offset} | {eof, Offset} | bof | cur | eof</v>
- <v>&nbsp;Offset = int()</v>
- <v>NewPosition = int()</v>
- <v>Reason = ext_posix() | terminated</v>
- </type>
<desc>
- <p>Sets the position of the file referenced by <c>IoDevice</c>
- to <c>Location</c>. Returns <c>{ok, NewPosition}</c> (as
+ <p>Sets the position of the file referenced by <c><anno>IoDevice</anno></c>
+ to <c><anno>Location</anno></c>. Returns
+ <c>{ok, <anno>NewPosition</anno>}</c> (as
absolute offset) if successful, otherwise
- <c>{error, Reason}</c>. <c>Location</c> is one of
- the following:</p>
+ <c>{error, <anno>Reason</anno>}</c>. <c><anno>Location</anno></c> is
+ one of the following:</p>
<taglist>
<tag><c>Offset</c></tag>
<item>
@@ -1167,7 +1048,8 @@ f.txt: {person, "kalle", 25}.
<taglist>
<tag><c>einval</c></tag>
<item>
- <p>Either <c>Location</c> was illegal, or it evaluated to a
+ <p>Either <c><anno>Location</anno></c> was illegal, or it
+ evaluated to a
negative offset in the file. Note that if the resulting
position is a negative value, the result is an error, and
after the call the file position is undefined.</p>
@@ -1176,22 +1058,14 @@ f.txt: {person, "kalle", 25}.
</desc>
</func>
<func>
- <name>pread(IoDevice, LocNums) -> {ok, DataL} | eof | {error, Reason}</name>
+ <name name="pread" arity="2"/>
<fsummary>Read from a file at certain positions</fsummary>
- <type>
- <v>IoDevice = io_device()</v>
- <v>LocNums = [{Location, Number}]</v>
- <v>&nbsp;Location -- see position/2</v>
- <v>&nbsp;Number = int()</v>
- <v>DataL = [Data]</v>
- <v>&nbsp;Data = [char()] | binary()</v>
- <v>Reason = ext_posix() | terminated</v>
- </type>
<desc>
<p>Performs a sequence of <c>pread/3</c> in one operation,
which is more efficient than calling them one at a time.
- Returns <c>{ok, [Data, ...]}</c> or <c>{error, Reason}</c>,
- where each <c>Data</c>, the result of the corresponding
+ Returns <c>{ok, [<anno>Data</anno>, ...]}</c> or
+ <c>{error, <anno>Reason</anno>}</c>,
+ where each <c><anno>Data</anno></c>, the result of the corresponding
<c>pread</c>, is either a list or a binary depending on
the mode of the file, or <c>eof</c> if the requested position
was beyond end of file.</p>
@@ -1199,76 +1073,53 @@ f.txt: {person, "kalle", 25}.
</desc>
</func>
<func>
- <name>pread(IoDevice, Location, Number) -> {ok, Data} | eof | {error, Reason}</name>
+ <name name="pread" arity="3"/>
<fsummary>Read from a file at a certain position</fsummary>
- <type>
- <v>IoDevice = io_device()</v>
- <v>Location -- see position/2</v>
- <v>Number = int()</v>
- <v>Data = [char()] | binary()</v>
- <v>Reason = ext_posix() | terminated</v>
- </type>
<desc>
<p>Combines <c>position/2</c> and <c>read/2</c> in one
operation, which is more efficient than calling them one at a
- time. If <c>IoDevice</c> has been opened in raw mode, some
- restrictions apply: <c>Location</c> is only allowed to be an
+ time. If <c><anno>IoDevice</anno></c> has been opened in raw mode,
+ some restrictions apply: <c><anno>Location</anno></c> is only allowed
+ to be an
integer; and the current position of the file is undefined
after the operation.</p>
<p>As the position is given as a byte-offset, special caution has to be taken when working with files where <c>encoding</c> is set to something else than <c>latin1</c>, as not every byte position will be a valid character boundary on such a file.</p>
</desc>
</func>
<func>
- <name>pwrite(IoDevice, LocBytes) -> ok | {error, {N, Reason}}</name>
+ <name name="pwrite" arity="2"/>
<fsummary>Write to a file at certain positions</fsummary>
- <type>
- <v>IoDevice = io_device()</v>
- <v>LocBytes = [{Location, Bytes}]</v>
- <v>&nbsp;Location -- see position/2</v>
- <v>&nbsp;Bytes = iodata()</v>
- <v>N = int()</v>
- <v>Reason = ext_posix() | terminated</v>
- </type>
<desc>
<p>Performs a sequence of <c>pwrite/3</c> in one operation,
which is more efficient than calling them one at a time.
- Returns <c>ok</c> or <c>{error, {N, Reason}}</c>, where
- <c>N</c> is the number of successful writes that was done
+ Returns <c>ok</c> or <c>{error, {<anno>N</anno>,
+ <anno>Reason</anno>}}</c>, where
+ <c><anno>N</anno></c> is the number of successful writes that was done
before the failure.</p>
<p>When positioning in a file with other <c>encoding</c> than <c>latin1</c>, caution must be taken to set the position on a correct character boundary, see <seealso marker="#position/2">position/2</seealso> for details.</p>
</desc>
</func>
<func>
- <name>pwrite(IoDevice, Location, Bytes) -> ok | {error, Reason}</name>
+ <name name="pwrite" arity="3"/>
<fsummary>Write to a file at a certain position</fsummary>
- <type>
- <v>IoDevice = io_device()</v>
- <v>Location -- see position/2</v>
- <v>Bytes = iodata()</v>
- <v>Reason = ext_posix() | terminated</v>
- </type>
<desc>
<p>Combines <c>position/2</c> and <c>write/2</c> in one
operation, which is more efficient than calling them one at a
- time. If <c>IoDevice</c> has been opened in raw mode, some
- restrictions apply: <c>Location</c> is only allowed to be an
+ time. If <c><anno>IoDevice</anno></c> has been opened in raw mode,
+ some restrictions apply: <c><anno>Location</anno></c> is only allowed
+ to be an
integer; and the current position of the file is undefined
after the operation.</p>
<p>When positioning in a file with other <c>encoding</c> than <c>latin1</c>, caution must be taken to set the position on a correct character boundary, see <seealso marker="#position/2">position/2</seealso> for details.</p>
</desc>
</func>
<func>
- <name>read(IoDevice, Number) -> {ok, Data} | eof | {error, Reason}</name>
+ <name name="read" arity="2"/>
<fsummary>Read from a file</fsummary>
- <type>
- <v>IoDevice = io_device()</v>
- <v>Number = int()</v>
- <v>Data = [char()] | binary()</v>
- <v>Reason = ext_posix() | terminated</v>
- </type>
<desc>
- <p>Reads <c>Number</c> bytes/characters from the file referenced by
- <c>IoDevice</c>. The functions <c>read/2</c>, <c>pread/3</c>
+ <p>Reads <c><anno>Number</anno></c> bytes/characters from the file
+ referenced by <c><anno>IoDevice</anno></c>. The functions
+ <c>read/2</c>, <c>pread/3</c>
and <c>read_line/1</c> are the only ways to read from a file
opened in raw mode (although they work for normally opened
files, too).</p>
@@ -1276,7 +1127,7 @@ f.txt: {person, "kalle", 25}.
<p>Also if <c>encoding</c> is set to something else than <c>latin1</c>, the <c>read/3</c> call will fail if the data contains characters larger than 255, why the <seealso marker="stdlib:io">io(3)</seealso> module is to be preferred when reading such a file.</p>
<p>The function returns:</p>
<taglist>
- <tag><c>{ok, Data}</c></tag>
+ <tag><c>{ok, <anno>Data</anno>}</c></tag>
<item>
<p>If the file was opened in binary mode, the read bytes are
returned in a binary, otherwise in a list. The list or
@@ -1285,10 +1136,10 @@ f.txt: {person, "kalle", 25}.
</item>
<tag><c>eof</c></tag>
<item>
- <p>Returned if <c>Number>0</c> and end of file was reached
- before anything at all could be read.</p>
+ <p>Returned if <c><anno>Number</anno>>0</c> and end of file was
+ reached before anything at all could be read.</p>
</item>
- <tag><c>{error, Reason}</c></tag>
+ <tag><c>{error, <anno>Reason</anno>}</c></tag>
<item>
<p>An error occurred.</p>
</item>
@@ -1307,17 +1158,14 @@ f.txt: {person, "kalle", 25}.
</desc>
</func>
<func>
- <name>read_file(Filename) -> {ok, Binary} | {error, Reason}</name>
+ <name name="read_file" arity="1"/>
<fsummary>Read a file</fsummary>
- <type>
- <v>Filename = name()</v>
- <v>Binary = binary()</v>
- <v>Reason = ext_posix() | terminated | system_limit</v>
- </type>
<desc>
- <p>Returns <c>{ok, Binary}</c>, where <c>Binary</c> is a binary
- data object that contains the contents of <c>Filename</c>, or
- <c>{error, Reason}</c> if an error occurs.</p>
+ <p>Returns <c>{ok, <anno>Binary</anno>}</c>, where
+ <c><anno>Binary</anno></c> is a binary
+ data object that contains the contents of
+ <c><anno>Filename</anno></c>, or
+ <c>{error, <anno>Reason</anno>}</c> if an error occurs.</p>
<p>Typical error reasons:</p>
<taglist>
<tag><c>enoent</c></tag>
@@ -1346,17 +1194,13 @@ f.txt: {person, "kalle", 25}.
</desc>
</func>
<func>
- <name>read_file_info(Filename) -> {ok, FileInfo} | {error, Reason}</name>
+ <name name="read_file_info" arity="1"/>
<fsummary>Get information about a file</fsummary>
- <type>
- <v>Filename = name()</v>
- <v>FileInfo = #file_info{}</v>
- <v>Reason = ext_posix()</v>
- </type>
<desc>
<p>Retrieves information about a file. Returns
- <c>{ok, FileInfo}</c> if successful, otherwise
- <c>{error, Reason}</c>. <c>FileInfo</c> is a record
+ <c>{ok, <anno>FileInfo</anno>}</c> if successful, otherwise
+ <c>{error, <anno>Reason</anno>}</c>. <c><anno>FileInfo</anno></c>
+ is a record
<c>file_info</c>, defined in the Kernel include file
<c>file.hrl</c>. Include the following directive in the module
from which the function is called:</p>
@@ -1364,7 +1208,7 @@ f.txt: {person, "kalle", 25}.
-include_lib("kernel/include/file.hrl").</code>
<p>The record <c>file_info</c> contains the following fields.</p>
<taglist>
- <tag><c>size = int()</c></tag>
+ <tag><c>size = integer()</c></tag>
<item>
<p>Size of file in bytes.</p>
</item>
@@ -1391,7 +1235,7 @@ f.txt: {person, "kalle", 25}.
the file or the inode was changed. In Windows, it is
the create time.</p>
</item>
- <tag><c>mode = int()</c></tag>
+ <tag><c>mode = integer()</c></tag>
<item>
<p>The file permissions as the sum of the following bit
values:</p>
@@ -1422,33 +1266,33 @@ f.txt: {person, "kalle", 25}.
<p>On Unix platforms, other bits than those listed above
may be set.</p>
</item>
- <tag><c>links = int()</c></tag>
+ <tag><c>links = integer()</c></tag>
<item>
<p>Number of links to the file (this will always be 1 for
file systems which have no concept of links).</p>
</item>
- <tag><c>major_device = int()</c></tag>
+ <tag><c>major_device = integer()</c></tag>
<item>
<p>Identifies the file system where the file is located.
In Windows, the number indicates a drive as follows:
0 means A:, 1 means B:, and so on.</p>
</item>
- <tag><c>minor_device = int()</c></tag>
+ <tag><c>minor_device = integer()</c></tag>
<item>
<p>Only valid for character devices on Unix. In all other
cases, this field is zero.</p>
</item>
- <tag><c>inode = int()</c></tag>
+ <tag><c>inode = integer()</c></tag>
<item>
<p>Gives the <c>inode</c> number. On non-Unix file systems,
this field will be zero.</p>
</item>
- <tag><c>uid = int()</c></tag>
+ <tag><c>uid = integer()</c></tag>
<item>
<p>Indicates the owner of the file. Will be zero for
non-Unix file systems.</p>
</item>
- <tag><c>gid = int()</c></tag>
+ <tag><c>gid = integer()</c></tag>
<item>
<p>Gives the group that the owner of the file belongs to.
Will be zero for non-Unix file systems.</p>
@@ -1474,21 +1318,16 @@ f.txt: {person, "kalle", 25}.
</desc>
</func>
<func>
- <name>read_line(IoDevice) -> {ok, Data} | eof | {error, Reason}</name>
+ <name name="read_line" arity="1"/>
<fsummary>Read a line from a file</fsummary>
- <type>
- <v>IoDevice = io_device()</v>
- <v>Data = [char()] | binary()</v>
- <v>Reason = ext_posix() | terminated</v>
- </type>
<desc>
<p>Reads a line of bytes/characters from the file referenced by
- <c>IoDevice</c>. Lines are defined to be delimited by the linefeed (LF, <c>\n</c>) character, but any carriage return (CR, <c>\r</c>) followed by a newline is also treated as a single LF character (the carriage return is silently ignored). The line is returned <em>including</em> the LF, but excluding any CR immediately followed by a LF. This behaviour is consistent with the behaviour of <seealso marker="stdlib:io#get_line/2">io:get_line/2</seealso>. If end of file is reached without any LF ending the last line, a line with no trailing LF is returned.</p>
+ <c><anno>IoDevice</anno></c>. Lines are defined to be delimited by the linefeed (LF, <c>\n</c>) character, but any carriage return (CR, <c>\r</c>) followed by a newline is also treated as a single LF character (the carriage return is silently ignored). The line is returned <em>including</em> the LF, but excluding any CR immediately followed by a LF. This behaviour is consistent with the behaviour of <seealso marker="stdlib:io#get_line/2">io:get_line/2</seealso>. If end of file is reached without any LF ending the last line, a line with no trailing LF is returned.</p>
<p>The function can be used on files opened in <c>raw</c> mode. It is however inefficient to use it on <c>raw</c> files if the file is not opened with the option <c>{read_ahead, Size}</c> specified, why combining <c>raw</c> and <c>{read_ahead, Size}</c> is highly recommended when opening a text file for raw line oriented reading.</p>
<p>If <c>encoding</c> is set to something else than <c>latin1</c>, the <c>read_line/1</c> call will fail if the data contains characters larger than 255, why the <seealso marker="stdlib:io">io(3)</seealso> module is to be preferred when reading such a file.</p>
<p>The function returns:</p>
<taglist>
- <tag><c>{ok, Data}</c></tag>
+ <tag><c>{ok, <anno>Data</anno>}</c></tag>
<item>
<p>One line from the file is returned, including the trailing LF, but with CRLF sequences replaced by a single LF (see above).</p>
<p>If the file was opened in binary mode, the read bytes are
@@ -1499,7 +1338,7 @@ f.txt: {person, "kalle", 25}.
<p>Returned if end of file was reached
before anything at all could be read.</p>
</item>
- <tag><c>{error, Reason}</c></tag>
+ <tag><c>{error, <anno>Reason</anno>}</c></tag>
<item>
<p>An error occurred.</p>
</item>
@@ -1518,23 +1357,19 @@ f.txt: {person, "kalle", 25}.
</desc>
</func>
<func>
- <name>read_link(Name) -> {ok, Filename} | {error, Reason}</name>
+ <name name="read_link" arity="1"/>
<fsummary>See what a link is pointing to</fsummary>
- <type>
- <v>Name = name()</v>
- <v>Filename = string()</v>
- <v>Reason = ext_posix()</v>
- </type>
<desc>
- <p>This function returns <c>{ok, Filename}</c> if <c>Name</c>
- refers to a symbolic link or <c>{error, Reason}</c> otherwise.
+ <p>This function returns <c>{ok, <anno>Filename</anno>}</c> if
+ <c><anno>Name</anno></c> refers to a symbolic link or
+ <c>{error, <anno>Reason</anno>}</c> otherwise.
On platforms that do not support symbolic links, the return
value will be <c>{error,enotsup}</c>.</p>
<p>Typical error reasons:</p>
<taglist>
<tag><c>einval</c></tag>
<item>
- <p><c>Linkname</c> does not refer to a symbolic link.</p>
+ <p><c><anno>Name</anno></c> does not refer to a symbolic link.</p>
</item>
<tag><c>enoent</c></tag>
<item>
@@ -1548,34 +1383,26 @@ f.txt: {person, "kalle", 25}.
</desc>
</func>
<func>
- <name>read_link_info(Name) -> {ok, FileInfo} | {error, Reason}</name>
+ <name name="read_link_info" arity="1"/>
<fsummary>Get information about a link or file</fsummary>
- <type>
- <v>Name = name()</v>
- <v>FileInfo = #file_info{}, see read_file_info/1</v>
- <v>Reason = ext_posix()</v>
- </type>
<desc>
<p>This function works like <c>read_file_info/1</c>, except that
- if <c>Name</c> is a symbolic link, information about the link
- will be returned in the <c>file_info</c> record and
+ if <c><anno>Name</anno></c> is a symbolic link, information about
+ the link will be returned in the <c>file_info</c> record and
the <c>type</c> field of the record will be set to
<c>symlink</c>.</p>
- <p>If <c>Name</c> is not a symbolic link, this function returns
+ <p>If <c><anno>Name</anno></c> is not a symbolic link, this function returns
exactly the same result as <c>read_file_info/1</c>.
On platforms that do not support symbolic links, this function
is always equivalent to <c>read_file_info/1</c>.</p>
</desc>
</func>
<func>
- <name>rename(Source, Destination) -> ok | {error, Reason}</name>
+ <name name="rename" arity="2"/>
<fsummary>Rename a file</fsummary>
- <type>
- <v>Source = Destination = name()</v>
- <v>Reason = ext_posix()</v>
- </type>
<desc>
- <p>Tries to rename the file <c>Source</c> to <c>Destination</c>.
+ <p>Tries to rename the file <c><anno>Source</anno></c> to
+ <c><anno>Destination</anno></c>.
It can be used to move files (and directories) between
directories, but it is not sufficient to specify
the destination only. The destination file name must also be
@@ -1593,25 +1420,28 @@ f.txt: {person, "kalle", 25}.
<tag><c>eacces</c></tag>
<item>
<p>Missing read or write permissions for the parent
- directories of <c>Source</c> or <c>Destination</c>. On
+ directories of <c><anno>Source</anno></c> or
+ <c><anno>Destination</anno></c>. On
some platforms, this error is given if either
- <c>Source</c> or <c>Destination</c> is open.</p>
+ <c><anno>Source</anno></c> or <c><anno>Destination</anno></c>
+ is open.</p>
</item>
<tag><c>eexist</c></tag>
<item>
- <p><c>Destination</c> is not an empty directory. On some
- platforms, also given when <c>Source</c> and
- <c>Destination</c> are not of the same type.</p>
+ <p><c><anno>Destination</anno></c> is not an empty directory.
+ On some platforms, also given when <c><anno>Source</anno></c> and
+ <c><anno>Destination</anno></c> are not of the same type.</p>
</item>
<tag><c>einval</c></tag>
<item>
- <p><c>Source</c> is a root directory, or <c>Destination</c>
- is a sub-directory of <c>Source</c>.</p>
+ <p><c><anno>Source</anno></c> is a root directory, or
+ <c><anno>Destination</anno></c>
+ is a sub-directory of <c><anno>Source</anno></c>.</p>
</item>
<tag><c>eisdir</c></tag>
<item>
- <p><c>Destination</c> is a directory, but <c>Source</c> is
- not.</p>
+ <p><c><anno>Destination</anno></c> is a directory, but
+ <c><anno>Source</anno></c> is not.</p>
</item>
<tag><c>enoent</c></tag>
<item>
@@ -1619,35 +1449,28 @@ f.txt: {person, "kalle", 25}.
</item>
<tag><c>enotdir</c></tag>
<item>
- <p><c>Source</c> is a directory, but <c>Destination</c> is
- not.</p>
+ <p><c><anno>Source</anno></c> is a directory, but
+ <c><anno>Destination</anno></c> is not.</p>
</item>
<tag><c>exdev</c></tag>
<item>
- <p><c>Source</c> and <c>Destination</c> are on different
- file systems.</p>
+ <p><c><anno>Source</anno></c> and <c><anno>Destination</anno></c>
+ are on different file systems.</p>
</item>
</taglist>
</desc>
</func>
<func>
- <name>script(Filename) -> {ok, Value} | {error, Reason}</name>
+ <name name="script" arity="1"/>
<fsummary>Evaluate and return the value of Erlang expressions in a file</fsummary>
- <type>
- <v>Filename = name()</v>
- <v>Value = term()</v>
- <v>Reason = ext_posix() | terminated | system_limit
- | {Line, Mod, Term}</v>
- <v>&nbsp;Line, Mod, Term -- see below</v>
- </type>
<desc>
<p>Reads and evaluates Erlang expressions, separated by '.' (or
',', a sequence of expressions is also an expression), from
the file. Returns one of the following:</p>
<taglist>
- <tag><c>{ok, Value}</c></tag>
+ <tag><c>{ok, <anno>Value</anno>}</c></tag>
<item>
- <p>The file was read and evaluated. <c>Value</c> is
+ <p>The file was read and evaluated. <c><anno>Value</anno></c> is
the value of the last expression.</p>
</item>
<tag><c>{error, atom()}</c></tag>
@@ -1656,7 +1479,8 @@ f.txt: {person, "kalle", 25}.
See <seealso marker="#open/2">open/2</seealso> for a list
of typical error codes.</p>
</item>
- <tag><c>{error, {Line, Mod, Term}}</c></tag>
+ <tag><c>{error, {<anno>Line</anno>, <anno>Mod</anno>,
+ <anno>Term</anno>}}</c></tag>
<item>
<p>An error occurred when interpreting the Erlang
expressions in the file. Use <c>format_error/1</c> to
@@ -1667,33 +1491,21 @@ f.txt: {person, "kalle", 25}.
</desc>
</func>
<func>
- <name>script(Filename, Bindings) -> {ok, Value} | {error, Reason}</name>
+ <name name="script" arity="2"/>
<fsummary>Evaluate and return the value of Erlang expressions in a file</fsummary>
- <type>
- <v>Filename = name()</v>
- <v>Bindings -- see erl_eval(3)</v>
- <v>Value = term()</v>
- <v>Reason = ext_posix() | terminated | system_limit
- | {Line, Mod, Term}</v>
- <v>&nbsp;Line, Mod, Term -- see below</v>
- </type>
<desc>
<p>The same as <c>script/1</c> but the variable bindings
- <c>Bindings</c> are used in the evaluation. See
+ <c><anno>Bindings</anno></c> are used in the evaluation. See
<seealso marker="stdlib:erl_eval">erl_eval(3)</seealso> about
variable bindings.</p>
</desc>
</func>
<func>
- <name>set_cwd(Dir) -> ok | {error,Reason}</name>
+ <name name="set_cwd" arity="1"/>
<fsummary>Set the current working directory</fsummary>
- <type>
- <v>Dir = name()</v>
- <v>Reason = ext_posix()</v>
- </type>
<desc>
<p>Sets the current working directory of the file server to
- <c>Dir</c>. Returns <c>ok</c> if successful.</p>
+ <c><anno>Dir</anno></c>. Returns <c>ok</c> if successful.</p>
<p>Typical error reasons are:</p>
<taglist>
<tag><c>enoent</c></tag>
@@ -1702,8 +1514,8 @@ f.txt: {person, "kalle", 25}.
</item>
<tag><c>enotdir</c></tag>
<item>
- <p>A component of <c>Dir</c> is not a directory. On some
- platforms, <c>enoent</c> is returned.</p>
+ <p>A component of <c><anno>Dir</anno></c> is not a directory.
+ On some platforms, <c>enoent</c> is returned.</p>
</item>
<tag><c>eacces</c></tag>
<item>
@@ -1712,23 +1524,21 @@ f.txt: {person, "kalle", 25}.
</item>
<tag><c>badarg</c></tag>
<item>
- <p><c>Filename</c> had an improper type, such as tuple.</p>
+ <p><c><anno>Dir</anno></c> had an improper type,
+ such as tuple.</p>
</item>
</taglist>
<warning>
- <p>In a future release, a bad type for the <c>Filename</c>
+ <p>In a future release, a bad type for the
+ <c><anno>Dir</anno></c>
argument will probably generate an exception.</p>
<p></p>
</warning>
</desc>
</func>
<func>
- <name>sync(IoDevice) -> ok | {error, Reason}</name>
+ <name name="sync" arity="1"/>
<fsummary>Synchronizes the in-memory state of a file with that on the physical medium</fsummary>
- <type>
- <v>IoDevice = io_device()</v>
- <v>Reason = ext_posix() | terminated</v>
- </type>
<desc>
<p>Makes sure that any buffers kept by the operating system
(not by the Erlang runtime system) are written to disk. On
@@ -1743,12 +1553,8 @@ f.txt: {person, "kalle", 25}.
</desc>
</func>
<func>
- <name>datasync(IoDevice) -> ok | {error, Reason}</name>
+ <name name="datasync" arity="1"/>
<fsummary>Synchronizes the in-memory data of a file, ignoring most of its metadata, with that on the physical medium</fsummary>
- <type>
- <v>IoDevice = io_device()</v>
- <v>Reason = ext_posix() | terminated</v>
- </type>
<desc>
<p>Makes sure that any buffers kept by the operating system
(not by the Erlang runtime system) are written to disk. In
@@ -1770,32 +1576,23 @@ f.txt: {person, "kalle", 25}.
</desc>
</func>
<func>
- <name>truncate(IoDevice) -> ok | {error, Reason}</name>
+ <name name="truncate" arity="1"/>
<fsummary>Truncate a file</fsummary>
- <type>
- <v>IoDevice = io_device()</v>
- <v>Reason = ext_posix() | terminated</v>
- </type>
<desc>
- <p>Truncates the file referenced by <c>IoDevice</c> at
+ <p>Truncates the file referenced by <c><anno>IoDevice</anno></c> at
the current position. Returns <c>ok</c> if successful,
- otherwise <c>{error, Reason}</c>.</p>
+ otherwise <c>{error, <anno>Reason</anno>}</c>.</p>
</desc>
</func>
<func>
- <name>write(IoDevice, Bytes) -> ok | {error, Reason}</name>
+ <name name="write" arity="2"/>
<fsummary>Write to a file</fsummary>
- <type>
- <v>IoDevice = io_device()</v>
- <v>Bytes = iodata()</v>
- <v>Reason = ext_posix() | terminated</v>
- </type>
<desc>
- <p>Writes <c>Bytes</c> to the file referenced by
- <c>IoDevice</c>. This function is the only way to write to a
+ <p>Writes <c><anno>Bytes</anno></c> to the file referenced by
+ <c><anno>IoDevice</anno></c>. This function is the only way to write to a
file opened in raw mode (although it works for normally
opened files, too). Returns <c>ok</c> if successful, and
- <c>{error, Reason}</c> otherwise.</p>
+ <c>{error, <anno>Reason</anno>}</c> otherwise.</p>
<p>If the file is opened with <c>encoding</c> set to something else than <c>latin1</c>, each byte written might result in several bytes actually being written to the file, as the byte range 0..255 might represent anything between one and four bytes depending on value and UTF encoding type.</p>
<p>Typical error reasons are:</p>
<taglist>
@@ -1811,18 +1608,14 @@ f.txt: {person, "kalle", 25}.
</desc>
</func>
<func>
- <name>write_file(Filename, Bytes) -> ok | {error, Reason}</name>
+ <name name="write_file" arity="2"/>
<fsummary>Write a file</fsummary>
- <type>
- <v>Filename = name()</v>
- <v>Bytes = iodata()</v>
- <v>Reason = ext_posix() | terminated | system_limit</v>
- </type>
<desc>
- <p>Writes the contents of the iodata term <c>Bytes</c> to the
- file <c>Filename</c>. The file is created if it does not
+ <p>Writes the contents of the iodata term <c><anno>Bytes</anno></c>
+ to the file <c><anno>Filename</anno></c>.
+ The file is created if it does not
exist. If it exists, the previous contents are
- overwritten. Returns <c>ok</c>, or <c>{error, Reason}</c>.</p>
+ overwritten. Returns <c>ok</c>, or <c>{error, <anno>Reason</anno>}</c>.</p>
<p>Typical error reasons are:</p>
<taglist>
<tag><c>enoent</c></tag>
@@ -1851,33 +1644,23 @@ f.txt: {person, "kalle", 25}.
</desc>
</func>
<func>
- <name>write_file(Filename, Bytes, Modes) -> ok | {error, Reason}</name>
+ <name name="write_file" arity="3"/>
<fsummary>Write a file</fsummary>
- <type>
- <v>Filename = name()</v>
- <v>Bytes = iodata()</v>
- <v>Modes = [Mode] -- see open/2</v>
- <v>Reason = ext_posix() | terminated | system_limit</v>
- </type>
<desc>
<p>Same as <c>write_file/2</c>, but takes a third argument
- <c>Modes</c>, a list of possible modes, see
+ <c><anno>Modes</anno></c>, a list of possible modes, see
<seealso marker="#open/2">open/2</seealso>. The mode flags
<c>binary</c> and <c>write</c> are implicit, so they should
not be used.</p>
</desc>
</func>
<func>
- <name>write_file_info(Filename, FileInfo) -> ok | {error, Reason}</name>
+ <name name="write_file_info" arity="2"/>
<fsummary>Change information about a file</fsummary>
- <type>
- <v>Filename = name()</v>
- <v>FileInfo = #file_info{} -- see also read_file_info/1</v>
- <v>Reason = ext_posix()</v>
- </type>
<desc>
<p>Change file information. Returns <c>ok</c> if successful,
- otherwise <c>{error, Reason}</c>. <c>FileInfo</c> is a record
+ otherwise <c>{error, <anno>Reason</anno>}</c>.
+ <c><anno>FileInfo</anno></c> is a record
<c>file_info</c>, defined in the Kernel include file
<c>file.hrl</c>. Include the following directive in the module
from which the function is called:</p>
@@ -1901,7 +1684,7 @@ f.txt: {person, "kalle", 25}.
time). On Windows, this field is the new creation time to
set for the file.</p>
</item>
- <tag><c>mode = int()</c></tag>
+ <tag><c>mode = integer()</c></tag>
<item>
<p>The file permissions as the sum of the following bit
values:</p>
@@ -1932,12 +1715,12 @@ f.txt: {person, "kalle", 25}.
<p>On Unix platforms, other bits than those listed above
may be set.</p>
</item>
- <tag><c>uid = int()</c></tag>
+ <tag><c>uid = integer()</c></tag>
<item>
<p>Indicates the owner of the file. Ignored for non-Unix
file systems.</p>
</item>
- <tag><c>gid = int()</c></tag>
+ <tag><c>gid = integer()</c></tag>
<item>
<p>Gives the group that the owner of the file belongs to.
Ignored non-Unix file systems.</p>
diff --git a/lib/kernel/doc/src/gen_sctp.xml b/lib/kernel/doc/src/gen_sctp.xml
index fb09092f1c..5ceb82ae41 100644
--- a/lib/kernel/doc/src/gen_sctp.xml
+++ b/lib/kernel/doc/src/gen_sctp.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2007</year><year>2010</year>
+ <year>2007</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -65,77 +65,71 @@
<item><seealso marker="#seealso">SEE ALSO</seealso></item>
<item><seealso marker="#authors">AUTHORS</seealso></item>
</list>
+ <marker id="types"></marker>
</section>
- <section>
- <marker id="types"></marker>
- <title>DATA TYPES</title>
- <marker id="type-assoc_id"></marker>
- <taglist>
- <tag><c>assoc_id()</c></tag>
- <item>
+ <datatypes>
+ <datatype>
+ <name name="assoc_id"/>
+ <desc>
<p>An opaque term returned in for example #sctp_paddr_change{}
that identifies an association for an SCTP socket. The term
is opaque except for the special value <c>0</c> that has a
- meaning such as "the whole endpoint" or "all future associations".</p>
- <marker id="type-charlist"></marker>
- </item>
- <tag><c>charlist() = [char()]</c></tag>
- <item> <marker id="type-iolist"></marker>
-</item>
- <tag><c>iolist() = [char() | binary()]</c></tag>
- <item> <marker id="type-ip_address"></marker>
-</item>
- <tag><c>ip_address()</c></tag>
- <item>
+ meaning such as "the whole endpoint" or "all future associations".
+ </p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="hostname"/>
+ </datatype>
+ <datatype>
+ <name name="ip_address"/>
+ <desc>
<p>Represents an address of an SCTP socket.
It is a tuple as explained in
<seealso marker="inet">inet(3)</seealso>.</p>
- <marker id="type-port_number"></marker>
- </item>
- <tag><c>port_number() = 0 .. 65535</c></tag>
- <item> <marker id="type-posix"></marker>
-</item>
- <tag><c>posix()</c></tag>
- <item>
- <p>See
- <seealso marker="inet#error_codes">inet(3); POSIX Error Codes.</seealso></p>
- <marker id="type-sctp_option"></marker>
- </item>
- <tag><c>sctp_option()</c></tag>
- <item>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="port_number"/>
+ </datatype>
+ <datatype>
+ <name name="posix"/>
+ <desc>
+ <p>See <seealso marker="inet#error_codes">
+ inet(3); POSIX Error Codes</seealso>.</p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="sctp_option"/>
+ <desc>
<p>One of the
<seealso marker="#options">SCTP Socket Options.</seealso></p>
<marker id="type-sctp_socket"></marker>
- </item>
- <tag><c>sctp_socket()</c></tag>
- <item>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="sctp_socket"/>
+ <desc>
<p>Socket identifier returned from <c>open/*</c>.</p>
- <marker id="type-timeout"></marker>
- </item>
- <tag><c>timeout() = int() | infinity</c></tag>
- <item>
- <p>Timeout used in SCTP connect and receive calls.</p>
- </item>
- </taglist>
- <marker id="exports"></marker>
- </section>
+ <marker id="exports"></marker>
+ </desc>
+ </datatype>
+ </datatypes>
+
<funcs>
<func>
- <name>abort(sctp_socket(), Assoc) -&gt; ok | {error, posix()}</name>
+ <name name="abort" arity="2"/>
<fsummary>Abnormally terminate the association given by Assoc, without flushing of unsent data</fsummary>
- <type>
- <v>Assoc = #sctp_assoc_change{}</v>
- </type>
<desc>
- <p>Abnormally terminates the association given by <c>Assoc</c>, without
+ <p>Abnormally terminates the association given by <c><anno>Assoc</anno></c>, without
flushing of unsent data. The socket itself remains open. Other
associations opened on this socket are still valid, and it can be
used in new associations.</p>
</desc>
</func>
<func>
- <name>close(sctp_socket()) -&gt; ok | {error, posix()}</name>
+ <name name="close" arity="1"/>
<fsummary>Completely close the socket and all associations on it</fsummary>
<desc>
<p>Completely closes the socket and all associations on it. The unsent
@@ -148,35 +142,26 @@
</desc>
</func>
<func>
- <name>connect(Socket, Addr, Port, Opts) -&gt; {ok,Assoc} | {error, posix()}</name>
+ <name name="connect" arity="4"/>
<fsummary>Same as <c>connect(Socket, Addr, Port, Opts, infinity)</c>.</fsummary>
<desc>
- <p>Same as <c>connect(Socket, Addr, Port, Opts, infinity)</c>.</p>
+ <p>Same as <c>connect(<anno>Socket</anno>, <anno>Addr</anno>, <anno>Port</anno>, <anno>Opts</anno>, infinity)</c>.</p>
</desc>
</func>
<func>
- <name>connect(Socket, Addr, Port, [Opt], Timeout) -&gt; {ok, Assoc} | {error, posix()}</name>
+ <name name="connect" arity="5"/>
<fsummary>Establish a new association for the socket <c>Socket</c>, with a peer (SCTP server socket)</fsummary>
- <type>
- <v>Socket = sctp_socket()</v>
- <v>Addr = ip_address() | Host</v>
- <v>Port = port_number()</v>
- <v>Opt = sctp_option()</v>
- <v>Timeout = timeout()</v>
- <v>Host = atom() | string()</v>
- <v>Assoc = #sctp_assoc_change{}</v>
- </type>
<desc>
- <p>Establishes a new association for the socket <c>Socket</c>,
+ <p>Establishes a new association for the socket <c><anno>Socket</anno></c>,
with the peer (SCTP server socket) given by
- <c>Addr</c> and <c>Port</c>. The <c>Timeout</c>,
+ <c><anno>Addr</anno></c> and <c><anno>Port</anno></c>. The <c><anno>Timeout</anno></c>,
is expressed in milliseconds. A socket can be associated with multiple peers.</p>
- <p><b>WARNING:</b>Using a value of <c>Timeout</c> less than
+ <p><b>WARNING:</b>Using a value of <c><anno>Timeout</anno></c> less than
the maximum time taken by the OS to establish an association (around 4.5 minutes
if the default values from RFC 4960 are used) can result in
inconsistent or incorrect return values. This is especially
- relevant for associations sharing the same <c>Socket</c>
+ relevant for associations sharing the same <c><anno>Socket</anno></c>
(i.e. source address and port) since the controlling process
blocks until <c>connect/*</c> returns.
<seealso marker="#connect_init/4">connect_init/*</seealso>
@@ -185,7 +170,7 @@
<p><marker id="record-sctp_assoc_change"></marker>
The result of <c>connect/*</c> is an <c>#sctp_assoc_change{}</c>
event which contains, in particular, the new
- <seealso marker="#type-assoc_id">Association ID:</seealso></p>
+ <seealso marker="#type-assoc_id">Association ID</seealso>.</p>
<pre>
#sctp_assoc_change{
state = atom(),
@@ -198,13 +183,13 @@
giving an <c>sctp_initmsg</c> option to <c>connect</c>
as in:</p>
<pre>
- connect(Socket, Ip, Port,
+ connect(<anno>Socket</anno>, Ip, <anno>Port</anno>,
[{sctp_initmsg,#sctp_initmsg{num_ostreams=OutStreams,
max_instreams=MaxInStreams}}]) </pre>
- <p>All options <c>Opt</c> are set on the socket before the
+ <p>All options <c><anno>Opt</anno></c> are set on the socket before the
association is attempted. If an option record has got undefined
field values, the options record is first read from the socket
- for those values. In effect, <c>Opt</c> option records only
+ for those values. In effect, <c><anno>Opt</anno></c> option records only
define field values to change before connecting.</p>
<p>The returned <c>outbound_streams</c> and <c>inbound_streams</c>
are the actual stream numbers on the socket, which may be different
@@ -242,27 +227,19 @@
</desc>
</func>
<func>
- <name>connect_init(Socket, Addr, Port, Opts) -&gt; ok | {error, posix()}</name>
+ <name name="connect_init" arity="4"/>
<fsummary>Same as <c>connect_init(Socket, Addr, Port, Opts, infinity)</c>.</fsummary>
<desc>
- <p>Same as <c>connect_init(Socket, Addr, Port, Opts, infinity)</c>.</p>
+ <p>Same as <c>connect_init(<anno>Socket</anno>, <anno>Addr</anno>, <anno>Port</anno>, <anno>Opts</anno>, infinity)</c>.</p>
</desc>
</func>
<func>
- <name>connect_init(Socket, Addr, Port, [Opt], Timeout) -&gt; ok | {error, posix()}</name>
+ <name name="connect_init" arity="5"/>
<fsummary>Initiate a new association for the socket <c>Socket</c>, with a peer (SCTP server socket)</fsummary>
- <type>
- <v>Socket = sctp_socket()</v>
- <v>Addr = ip_address() | Host</v>
- <v>Port = port_number()</v>
- <v>Opt = sctp_option()</v>
- <v>Timeout = timeout()</v>
- <v>Host = atom() | string()</v>
- </type>
<desc>
- <p>Initiates a new association for the socket <c>Socket</c>,
+ <p>Initiates a new association for the socket <c><anno>Socket</anno></c>,
with the peer (SCTP server socket) given by
- <c>Addr</c> and <c>Port</c>.</p>
+ <c><anno>Addr</anno></c> and <c><anno>Port</anno></c>.</p>
<p>The fundamental difference between this API
and <c>connect/*</c> is that the return value is that of the
underlying OS connect(2) system call. If <c>ok</c> is returned
@@ -275,64 +252,52 @@
active option.</p>
<p>The parameters are as described
in <seealso marker="#connect/5">connect/*</seealso>, with the
- exception of the <c>Timeout</c> value.</p>
- <p>The timer associated with <c>Timeout</c> only supervises
- IP resolution of <c>Addr</c></p>
+ exception of the <c><anno>Timeout</anno></c> value.</p>
+ <p>The timer associated with <c><anno>Timeout</anno></c> only supervises
+ IP resolution of <c><anno>Addr</anno></c></p>
</desc>
</func>
<func>
- <name>controlling_process(sctp_socket(), pid()) -&gt; ok</name>
+ <name name="controlling_process" arity="2"/>
<fsummary>Assign a new controlling process pid to the socket</fsummary>
<desc>
- <p>Assigns a new controlling process Pid to Socket. Same implementation
+ <p>Assigns a new controlling process <c><anno>Pid</anno></c> to <c><anno>Socket</anno></c>. Same implementation
as <c>gen_udp:controlling_process/2</c>.</p>
</desc>
</func>
<func>
- <name>eof(Socket, Assoc) -&gt; ok | {error, Reason}</name>
+ <name name="eof" arity="2"/>
<fsummary>Gracefully terminate the association given by Assoc, with flushing of all unsent data</fsummary>
- <type>
- <v>Socket = sctp_socket()</v>
- <v>Assoc = #sctp_assoc_change{}</v>
- </type>
<desc>
- <p>Gracefully terminates the association given by <c>Assoc</c>, with
+ <p>Gracefully terminates the association given by <c><anno>Assoc</anno></c>, with
flushing of all unsent data. The socket itself remains open. Other
associations opened on this socket are still valid, and it can be
used in new associations.</p>
</desc>
</func>
<func>
- <name>listen(Socket, IsServer) -&gt; ok | {error, Reason}</name>
+ <name name="listen" arity="2"/>
<fsummary>Set up a socket to listen.</fsummary>
- <type>
- <v>Socket = sctp_socket()</v>
- <v>IsServer = bool()</v>
- </type>
<desc>
<p>Sets up a socket to listen on the IP address and port number
- it is bound to. IsServer must be 'true' or 'false'.
+ it is bound to. <c><anno>IsServer</anno></c> must be <c>true</c>
+ or <c>false</c>.
In the contrast to TCP, in SCTP there is no listening queue length.
- If IsServer is 'true' the socket accepts new associations, i.e.
+ If <c><anno>IsServer</anno></c> is <c>true</c> the socket accepts new associations, i.e.
it will become an SCTP server socket.</p>
</desc>
</func>
<func>
- <name>open() -&gt; {ok, Socket} | {error, posix()}</name>
- <name>open(Port) -&gt; {ok, Socket} | {error, posix()}</name>
- <name>open([Opt]) -&gt; {ok, Socket} | {error, posix()}</name>
- <name>open(Port, [Opt]) -&gt; {ok, Socket} | {error, posix()}</name>
+ <name name="open" arity="0"/>
+ <name name="open" arity="1" clause_i="1"/>
+ <name name="open" arity="1" clause_i="2"/>
+ <name name="open" arity="2"/>
<fsummary>Create an SCTP socket and bind it to local addresses</fsummary>
- <type>
- <v>Opt = {ip,IP} | {ifaddr,IP} | {port,Port} | sctp_option()</v>
- <v>IP = ip_address() | any | loopback</v>
- <v>Port = port_number()</v>
- </type>
<desc>
<p>Creates an SCTP socket and binds it to the local addresses
- specified by all <c>{ip,IP}</c> (or synonymously <c>{ifaddr,IP}</c>)
+ specified by all <c>{ip,<anno>IP</anno>}</c> (or synonymously <c>{ifaddr,<anno>IP</anno>}</c>)
options (this feature is called SCTP multi-homing).
- The default <c>IP</c> and <c>Port</c> are <c>any</c>
+ The default <c><anno>IP</anno></c> and <c><anno>Port</anno></c> are <c>any</c>
and <c>0</c>, meaning bind to all local addresses on any
one free port.</p>
<p>A default set of socket <seealso marker="#options">options</seealso>
@@ -345,27 +310,16 @@
</desc>
</func>
<func>
- <name>recv(sctp_socket()) -&gt; {ok, {FromIP, FromPort, AncData, BinMsg}} | {error, Reason}</name>
- <name>recv(sctp_socket(), timeout()) -&gt; {ok, {FromIP, FromPort, AncData, Data}} | {error, Reason}</name>
+ <name name="recv" arity="1"/>
+ <name name="recv" arity="2"/>
<fsummary>Receive a message from a socket</fsummary>
- <type>
- <v>FromIP = ip_address()</v>
- <v>FromPort = port_number()</v>
- <v>AncData = [#sctp_sndrcvinfo{}]</v>
- <v>Data = binary() | charlist() | #sctp_sndrcvinfo{} |
- #sctp_assoc_change{} | #sctp_paddr_change{} |
- #sctp_adaptation_event{} </v>
- <v>Reason = posix() | #sctp_send_failed{} | #scpt_paddr_change{} |
- #sctp_pdapi_event{} | #sctp_remote_error{} |
- #sctp_shutdown_event{}</v>
- </type>
<desc>
- <p>Receives the <c>Data</c> message from any association of the socket.
+ <p>Receives the <c><anno>Data</anno></c> message from any association of the socket.
If the receive times out <c>{error,timeout</c> is returned.
The default timeout is <c>infinity</c>.
- <c>FromIP</c> and <c>FromPort</c> indicate the sender's address.</p>
- <p><c>AncData</c> is a list of Ancillary Data items which
- may be received along with the main <c>Data</c>.
+ <c><anno>FromIP</anno></c> and <c><anno>FromPort</anno></c> indicate the sender's address.</p>
+ <p><c><anno>AncData</anno></c> is a list of Ancillary Data items which
+ may be received along with the main <c><anno>Data</anno></c>.
This list can be empty, or contain a single
<seealso marker="#record-sctp_sndrcvinfo">#sctp_sndrcvinfo{}</seealso>
record, if receiving of such ancillary data is enabled
@@ -375,10 +329,10 @@
provide an easy way of determining the association and stream
over which the message has been received.
(An alternative way would be to get the Association ID from the
- <c>FromIP</c> and <c>FromPort</c> using the
+ <c><anno>FromIP</anno></c> and <c><anno>FromPort</anno></c> using the
<seealso marker="#option-sctp_get_peer_addr_info">sctp_get_peer_addr_info</seealso> socket option,
but this would still not produce the Stream number).</p>
- <p>The actual <c>Data</c> received may be a <c>binary()</c>,
+ <p>The actual <c><anno>Data</anno></c> received may be a <c>binary()</c>,
or <c>list()</c> of bytes (integers in the range 0 through 255)
depending on the socket mode, or an SCTP Event.
<marker id="sctp_events"></marker>
@@ -476,15 +430,10 @@
</desc>
</func>
<func>
- <name>send(Socket, SndRcvInfo, Data) -&gt; ok | {error, Reason}</name>
+ <name name="send" arity="3"/>
<fsummary>Send a message using an <c>#sctp_sndrcvinfo{}</c>record</fsummary>
- <type>
- <v>Socket = sctp_socket()</v>
- <v>SndRcvInfo = #sctp_sndrcvinfo{}</v>
- <v>Data = binary() | iolist()</v>
- </type>
<desc>
- <p>Sends the <c>Data</c> message with all sending parameters from a
+ <p>Sends the <c><anno>Data</anno></c> message with all sending parameters from a
<seealso marker="#record-sctp_sndrcvinfo">#sctp_sndrcvinfo{}</seealso> record.
This way, the user can specify the PPID (passed to the remote end)
and Context (passed to the local SCTP layer) which can be used
@@ -494,21 +443,15 @@
</desc>
</func>
<func>
- <name>send(Socket, Assoc, Stream, Data) -&gt; ok | {error, Reason}</name>
+ <name name="send" arity="4"/>
<fsummary>Send a message over an existing association and given stream</fsummary>
- <type>
- <v>Socket = sctp_socket()</v>
- <v>Assoc = #sctp_assoc_change{} | assoc_id()</v>
- <v>Stream = integer()</v>
- <v>Data = binary() | iolist()</v>
- </type>
<desc>
- <p>Sends <c>Data</c> message over an existing association and given
+ <p>Sends <c><anno>Data</anno></c> message over an existing association and given
stream.</p>
</desc>
</func>
<func>
- <name>error_string(integer()) -> ok | string() | undefined</name>
+ <name name="error_string" arity="1"/>
<fsummary>Translate an SCTP error number into a string</fsummary>
<desc>
<p>Translates an SCTP error number from for example
diff --git a/lib/kernel/doc/src/gen_tcp.xml b/lib/kernel/doc/src/gen_tcp.xml
index aa171c77c2..f1d42d9faa 100644
--- a/lib/kernel/doc/src/gen_tcp.xml
+++ b/lib/kernel/doc/src/gen_tcp.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1997</year><year>2010</year>
+ <year>1997</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -63,36 +63,45 @@ do_recv(Sock, Bs) ->
<p>For more examples, see the <seealso marker="#examples">examples</seealso> section.</p>
</description>
- <section>
- <title>DATA TYPES</title>
- <code type="none">
-ip_address()
- see inet(3)
-
-posix()
- see inet(3)
+ <datatypes>
+ <datatype>
+ <name name="hostname"/>
+ </datatype>
+ <datatype>
+ <name name="ip_address"/>
+ <desc>
+ <p>Represents an address of a TCP socket.
+ It is a tuple as explained in
+ <seealso marker="inet">inet(3)</seealso>.</p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="port_number"/>
+ </datatype>
+ <datatype>
+ <name name="posix"/>
+ <desc>
+ <p>See <seealso marker="inet#error_codes">
+ inet(3); POSIX Error Codes</seealso>.</p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name><marker id="type-socket">socket()</marker></name>
+ <desc>
+ <p>As returned by accept/1,2 and connect/3,4.</p>
+ <marker id="connect"></marker>
+ </desc>
+ </datatype>
+ </datatypes>
-socket()
- as returned by accept/1,2 and connect/3,4</code>
- <marker id="connect"></marker>
- </section>
<funcs>
<func>
- <name>connect(Address, Port, Options) -> {ok, Socket} | {error, Reason}</name>
- <name>connect(Address, Port, Options, Timeout) -> {ok, Socket} | {error, Reason}</name>
+ <name name="connect" arity="3"/>
+ <name name="connect" arity="4"/>
<fsummary>Connect to a TCP port</fsummary>
- <type>
- <v>Address = string() | atom() | ip_address()</v>
- <v>Port = 0..65535</v>
- <v>Options = [Opt]</v>
- <v>&nbsp;Opt -- see below</v>
- <v>Timeout = int() | infinity</v>
- <v>Socket = socket()</v>
- <v>Reason = posix()</v>
- </type>
<desc>
- <p>Connects to a server on TCP port <c>Port</c> on the host
- with IP address <c>Address</c>. The <c>Address</c> argument
+ <p>Connects to a server on TCP port <c><anno>Port</anno></c> on the host
+ with IP address <c><anno>Address</anno></c>. The <c><anno>Address</anno></c> argument
can be either a hostname, or an IP address.</p>
<p>The available options are:</p>
<taglist>
@@ -127,13 +136,13 @@ socket()
<item>
<p>Set up the socket for IPv4.</p>
</item>
- <tag>Opt</tag>
+ <tag><c>Opt</c></tag>
<item>
<p>See
<seealso marker="inet#setopts/2">inet:setopts/2</seealso>.</p>
</item>
</taglist>
- <p>Packets can be sent to the returned socket <c>Socket</c>
+ <p>Packets can be sent to the returned socket <c><anno>Socket</anno></c>
using <c>send/2</c>. Packets sent from the peer are delivered
as messages:</p>
<code type="none">
@@ -148,7 +157,7 @@ socket()
<p>unless <c>{active, false}</c> is specified in the option list
for the socket, in which case packets are retrieved by
calling <c>recv/2</c>.</p>
- <p>The optional <c>Timeout</c> parameter specifies a timeout in
+ <p>The optional <c><anno>Timeout</anno></c> parameter specifies a timeout in
milliseconds. The default value is <c>infinity</c>.</p>
<note>
<p>The default values for options given to <c>connect</c> can
@@ -159,19 +168,12 @@ socket()
</desc>
</func>
<func>
- <name>listen(Port, Options) -> {ok, ListenSocket} | {error, Reason}</name>
+ <name name="listen" arity="2"/>
<fsummary>Set up a socket to listen on a port</fsummary>
- <type>
- <v>Port = 0..65535</v>
- <v>Options = [Opt]</v>
- <v>&nbsp;Opt -- see below</v>
- <v>ListenSocket -- see below</v>
- <v>Reason = posix()</v>
- </type>
<desc>
- <p>Sets up a socket to listen on the port <c>Port</c> on
+ <p>Sets up a socket to listen on the port <c><anno>Port</anno></c> on
the local host.</p>
- <p>If <c>Port == 0</c>, the underlying OS assigns an available
+ <p>If <c><anno>Port</anno> == 0</c>, the underlying OS assigns an available
port number, use <c>inet:port/1</c> to retrieve it.</p>
<p>The available options are:</p>
<taglist>
@@ -214,7 +216,7 @@ socket()
<seealso marker="inet#setopts/2">inet:setopts/2</seealso>.</p>
</item>
</taglist>
- <p>The returned socket <c>ListenSocket</c> can only be used in
+ <p>The returned socket <c><anno>ListenSocket</anno></c> can only be used in
calls to <c>accept/1,2</c>.</p>
<note>
<p>The default values for options given to <c>listen</c> can
@@ -225,27 +227,23 @@ socket()
</desc>
</func>
<func>
- <name>accept(ListenSocket) -> {ok, Socket} | {error, Reason}</name>
- <name>accept(ListenSocket, Timeout) -> {ok, Socket} | {error, Reason}</name>
+ <name name="accept" arity="1"/>
+ <name name="accept" arity="2"/>
<fsummary>Accept an incoming connection request on a listen socket</fsummary>
- <type>
- <v>ListenSocket -- see listen/2</v>
- <v>Timeout = int() | infinity</v>
- <v>Socket = socket()</v>
- <v>Reason = closed | timeout | posix()</v>
- </type>
+ <type_desc variable="ListenSocket">Returned by <c>listen/2</c>.
+ </type_desc>
<desc>
<p>Accepts an incoming connection request on a listen socket.
- <c>Socket</c> must be a socket returned from <c>listen/2</c>.
- <c>Timeout</c> specifies a timeout value in ms, defaults to
+ <c><anno>Socket</anno></c> must be a socket returned from <c>listen/2</c>.
+ <c><anno>Timeout</anno></c> specifies a timeout value in ms, defaults to
<c>infinity</c>.</p>
- <p>Returns <c>{ok, Socket}</c> if a connection is established,
- or <c>{error, closed}</c> if <c>ListenSocket</c> is closed,
+ <p>Returns <c>{ok, <anno>Socket</anno>}</c> if a connection is established,
+ or <c>{error, closed}</c> if <c><anno>ListenSocket</anno></c> is closed,
or <c>{error, timeout}</c> if no connection is established
within the specified time. May also return a POSIX error
value if something else goes wrong, see inet(3) for possible
error values.</p>
- <p>Packets can be sent to the returned socket <c>Socket</c>
+ <p>Packets can be sent to the returned socket <c><anno>Socket</anno></c>
using <c>send/2</c>. Packets sent from the peer are delivered
as messages:</p>
<code type="none">
@@ -264,13 +262,8 @@ socket()
</desc>
</func>
<func>
- <name>send(Socket, Packet) -> ok | {error, Reason}</name>
+ <name name="send" arity="2"/>
<fsummary>Send a packet</fsummary>
- <type>
- <v>Socket = socket()</v>
- <v>Packet = [char()] | binary()</v>
- <v>Reason = posix()</v>
- </type>
<desc>
<p>Sends a packet on a socket. </p>
<p>There is no <c>send</c> call with timeout option, you use the
@@ -279,70 +272,52 @@ socket()
</desc>
</func>
<func>
- <name>recv(Socket, Length) -> {ok, Packet} | {error, Reason}</name>
- <name>recv(Socket, Length, Timeout) -> {ok, Packet} | {error, Reason}</name>
+ <name name="recv" arity="2"/>
+ <name name="recv" arity="3"/>
<fsummary>Receive a packet from a passive socket</fsummary>
- <type>
- <v>Socket = socket()</v>
- <v>Length = int()</v>
- <v>Packet = [char()] | binary() | HttpPacket</v>
- <v>Timeout = int() | infinity</v>
- <v>Reason = closed | posix()</v>
- <v>HttpPacket = see the description of <c>HttpPacket</c> in <seealso marker="erts:erlang#decode_packet/3">erlang:decode_packet/3</seealso></v>
- </type>
+ <type_desc variable="HttpPacket">See the description of
+ <c>HttpPacket</c> in <seealso marker="erts:erlang#decode_packet/3">
+ erlang:decode_packet/3</seealso>.
+ </type_desc>
<desc>
<p>This function receives a packet from a socket in passive
mode. A closed socket is indicated by a return value
<c>{error, closed}</c>.</p>
- <p>The <c>Length</c> argument is only meaningful when
+ <p>The <c><anno>Length</anno></c> argument is only meaningful when
the socket is in <c>raw</c> mode and denotes the number of
- bytes to read. If <c>Length</c> = 0, all available bytes are
- returned. If <c>Length</c> &gt; 0, exactly <c>Length</c>
+ bytes to read. If <c><anno>Length</anno></c> = 0, all available bytes are
+ returned. If <c><anno>Length</anno></c> &gt; 0, exactly <c><anno>Length</anno></c>
bytes are returned, or an error; possibly discarding less
- than <c>Length</c> bytes of data when the socket gets closed
+ than <c><anno>Length</anno></c> bytes of data when the socket gets closed
from the other side.</p>
- <p>The optional <c>Timeout</c> parameter specifies a timeout in
+ <p>The optional <c><anno>Timeout</anno></c> parameter specifies a timeout in
milliseconds. The default value is <c>infinity</c>.</p>
</desc>
</func>
<func>
- <name>controlling_process(Socket, Pid) -> ok | {error, Reason}</name>
+ <name name="controlling_process" arity="2"/>
<fsummary>Change controlling process of a socket</fsummary>
- <type>
- <v>Socket = socket()</v>
- <v>Pid = pid()</v>
- <v>Reason = closed | not_owner | posix()</v>
- </type>
<desc>
- <p>Assigns a new controlling process <c>Pid</c> to
- <c>Socket</c>. The controlling process is the process which
+ <p>Assigns a new controlling process <c><anno>Pid</anno></c> to
+ <c><anno>Socket</anno></c>. The controlling process is the process which
receives messages from the socket. If called by any other
process than the current controlling process,
<c>{error, eperm}</c> is returned.</p>
</desc>
</func>
<func>
- <name>close(Socket) -> ok | {error, Reason}</name>
+ <name name="close" arity="1"/>
<fsummary>Close a TCP socket</fsummary>
- <type>
- <v>Socket = socket()</v>
- <v>Reason = posix()</v>
- </type>
<desc>
<p>Closes a TCP socket.</p>
</desc>
</func>
<func>
- <name>shutdown(Socket, How) -> ok | {error, Reason}</name>
+ <name name="shutdown" arity="2"/>
<fsummary>Immediately close a socket</fsummary>
- <type>
- <v>Socket = socket()</v>
- <v>How = read | write | read_write</v>
- <v>Reason = posix()</v>
- </type>
<desc>
<p>Immediately close a socket in one or two directions.</p>
- <p><c>How == write</c> means closing the socket for writing,
+ <p><c><anno>How</anno> == write</c> means closing the socket for writing,
reading from it is still possible.</p>
<p>To be able to handle that the peer has done a shutdown on
the write side, the <c>{exit_on_close, false}</c> option
diff --git a/lib/kernel/doc/src/gen_udp.xml b/lib/kernel/doc/src/gen_udp.xml
index 71f2e9bd83..c0e783f508 100644
--- a/lib/kernel/doc/src/gen_udp.xml
+++ b/lib/kernel/doc/src/gen_udp.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1997</year><year>2009</year>
+ <year>1997</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -34,32 +34,43 @@
with sockets using the UDP protocol.</p>
</description>
- <section>
- <title>DATA TYPES</title>
- <code type="none">
-ip_address()
- see inet(3)
-
-posix()
- see inet(3)
+ <datatypes>
+ <datatype>
+ <name name="hostname"/>
+ </datatype>
+ <datatype>
+ <name name="ip_address"/>
+ <desc>
+ <p>Represents an address of a TCP socket.
+ It is a tuple as explained in
+ <seealso marker="inet">inet(3)</seealso>.</p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="port_number"/>
+ </datatype>
+ <datatype>
+ <name name="posix"/>
+ <desc>
+ <p>See <seealso marker="inet#error_codes">
+ inet(3); POSIX Error Codes</seealso>.</p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name><marker id="type-socket">socket()</marker></name>
+ <desc>
+ <p>As returned by open/1,2.</p>
+ </desc>
+ </datatype>
+ </datatypes>
-socket()
- as returned by open/1,2</code>
- </section>
<funcs>
<func>
- <name>open(Port) -> {ok, Socket} | {error, Reason}</name>
- <name>open(Port, Options) -> {ok, Socket} | {error, Reason}</name>
+ <name name="open" arity="1"/>
+ <name name="open" arity="2"/>
<fsummary>Associate a UDP port number with the process calling it</fsummary>
- <type>
- <v>Port = 0..65535</v>
- <v>Options = [Opt]</v>
- <v>&nbsp;Opt -- see below</v>
- <v>Socket = socket()</v>
- <v>Reason = posix()</v>
- </type>
<desc>
- <p>Associates a UDP port number (<c>Port</c>) with the calling
+ <p>Associates a UDP port number (<c><anno>Port</anno></c>) with the calling
process.</p>
<p>The available options are:</p>
<taglist>
@@ -96,7 +107,7 @@ socket()
<seealso marker="inet#setopts/2">inet:setopts/2</seealso>.</p>
</item>
</taglist>
- <p>The returned socket <c>Socket</c> is used to send packets
+ <p>The returned socket <c><anno>Socket</anno></c> is used to send packets
from this port with <c>send/4</c>. When UDP packets arrive at
the opened port, they are delivered as messages:</p>
<code type="none">
@@ -110,66 +121,42 @@ socket()
binary if the option <c>binary</c> was specified.</p>
<p>Default value for the receive buffer option is
<c>{recbuf, 8192}</c>.</p>
- <p>If <c>Port == 0</c>, the underlying OS assigns a free UDP
+ <p>If <c><anno>Port</anno> == 0</c>, the underlying OS assigns a free UDP
port, use <c>inet:port/1</c> to retrieve it.</p>
</desc>
</func>
<func>
- <name>send(Socket, Address, Port, Packet) -> ok | {error, Reason}</name>
+ <name name="send" arity="4"/>
<fsummary>Send a packet</fsummary>
- <type>
- <v>Socket = socket()</v>
- <v>Address = string() | atom() | ip_address()</v>
- <v>Port = 0..65535</v>
- <v>Packet = [char()] | binary()</v>
- <v>Reason = not_owner | posix()</v>
- </type>
<desc>
<p>Sends a packet to the specified address and port.
- The <c>Address</c> argument can be either a hostname, or an
+ The <c><anno>Address</anno></c> argument can be either a hostname, or an
IP address.</p>
</desc>
</func>
<func>
- <name>recv(Socket, Length) -> {ok, {Address, Port, Packet}} | {error, Reason}</name>
- <name>recv(Socket, Length, Timeout) -> {ok, {Address, Port, Packet}} | {error, Reason}</name>
+ <name name="recv" arity="2"/>
+ <name name="recv" arity="3"/>
<fsummary>Receive a packet from a passive socket</fsummary>
- <type>
- <v>Socket = socket()</v>
- <v>Length = int()</v>
- <v>Address = ip_address()</v>
- <v>Port = 0..65535</v>
- <v>Packet = [char()] | binary()</v>
- <v>Timeout = int() | infinity</v>
- <v>Reason = not_owner | posix()</v>
- </type>
<desc>
<p>This function receives a packet from a socket in passive
mode.</p>
- <p>The optional <c>Timeout</c> parameter specifies a timeout in
+ <p>The optional <c><anno>Timeout</anno></c> parameter specifies a timeout in
milliseconds. The default value is <c>infinity</c>.</p>
</desc>
</func>
<func>
- <name>controlling_process(Socket, Pid) -> ok</name>
+ <name name="controlling_process" arity="2"/>
<fsummary>Change controlling process of a socket</fsummary>
- <type>
- <v>Socket = socket()</v>
- <v>Pid = pid()</v>
- </type>
<desc>
- <p>Assigns a new controlling process <c>Pid</c> to
- <c>Socket</c>. The controlling process is the process which
+ <p>Assigns a new controlling process <c><anno>Pid</anno></c> to
+ <c><anno>Socket</anno></c>. The controlling process is the process which
receives messages from the socket.</p>
</desc>
</func>
<func>
- <name>close(Socket) -> ok | {error, Reason}</name>
+ <name name="close" arity="1"/>
<fsummary>Close a UDP socket</fsummary>
- <type>
- <v>Socket = socket()</v>
- <v>Reason = not_owner | posix()</v>
- </type>
<desc>
<p>Closes a UDP socket.</p>
</desc>
diff --git a/lib/kernel/doc/src/global.xml b/lib/kernel/doc/src/global.xml
index 077109d6c9..304a9b1d88 100644
--- a/lib/kernel/doc/src/global.xml
+++ b/lib/kernel/doc/src/global.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2009</year>
+ <year>1996</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -106,45 +106,37 @@
</description>
+ <datatypes>
+ <datatype>
+ <name name="id"/>
+ </datatype>
+ </datatypes>
+
<funcs>
<func>
- <name>del_lock(Id)</name>
- <name>del_lock(Id, Nodes) -> void()</name>
+ <name name="del_lock" arity="1"/>
+ <name name="del_lock" arity="2"/>
<fsummary>Delete a lock</fsummary>
- <type>
- <v>Id = {ResourceId, LockRequesterId}</v>
- <v>&nbsp;ResourceId = term()</v>
- <v>&nbsp;LockRequesterId = term()</v>
- <v>Nodes = [node()]</v>
- </type>
<desc>
- <p>Deletes the lock <c>Id</c> synchronously.</p>
+ <p>Deletes the lock <c><anno>Id</anno></c> synchronously.</p>
</desc>
</func>
<func>
- <name>notify_all_name(Name, Pid1, Pid2) -> none</name>
+ <name name="notify_all_name" arity="3"/>
<fsummary>Name resolving function that notifies both pids</fsummary>
- <type>
- <v>Name = term()</v>
- <v>Pid1 = Pid2 = pid()</v>
- </type>
<desc>
<p>This function can be used as a name resolving function for
<c>register_name/3</c> and <c>re_register_name/3</c>. It
unregisters both pids, and sends the message
- <c>{global_name_conflict, Name, OtherPid}</c> to both
+ <c>{global_name_conflict, <anno>Name</anno>, OtherPid}</c> to both
processes.</p>
</desc>
</func>
<func>
- <name>random_exit_name(Name, Pid1, Pid2) -> Pid1 | Pid2</name>
+ <name name="random_exit_name" arity="3"/>
<fsummary>Name resolving function that kills one pid</fsummary>
- <type>
- <v>Name = term()</v>
- <v>Pid1 = Pid2 = pid()</v>
- </type>
<desc>
<p>This function can be used as a name resolving function for
<c>register_name/3</c> and <c>re_register_name/3</c>. It
@@ -154,33 +146,27 @@
</func>
<func>
- <name>random_notify_name(Name, Pid1, Pid2) -> Pid1 | Pid2</name>
+ <name name="random_notify_name" arity="3"/>
<fsummary>Name resolving function that notifies one pid</fsummary>
- <type>
- <v>Name = term()</v>
- <v>Pid1 = Pid2 = pid()</v>
- </type>
<desc>
<p>This function can be used as a name resolving function for
<c>register_name/3</c> and <c>re_register_name/3</c>. It
randomly chooses one of the pids for registration, and sends
- the message <c>{global_name_conflict, Name}</c> to the other
+ the message <c>{global_name_conflict, <anno>Name</anno>}</c> to the other
pid.</p>
</desc>
</func>
<func>
- <name>register_name(Name, Pid)</name>
- <name>register_name(Name, Pid, Resolve) -> yes | no</name>
+ <name name="register_name" arity="2"/>
+ <name name="register_name" arity="3"/>
<fsummary>Globally register a name for a pid</fsummary>
- <type>
- <v>Name = term()</v>
- <v>Pid = pid()</v>
- <v>Resolve = fun() or {Module, Function} where</v>
- <v>&nbsp;&nbsp;Resolve(Name, Pid, Pid2) -> Pid | Pid2 | none</v>
- </type>
+ <type name="method"/>
+ <type_desc name="method">{<c>Module</c>, <c>Function</c>}
+ is also allowed
+ </type_desc>
<desc>
- <p>Globally associates the name <c>Name</c> with a pid, that is,
+ <p>Globally associates the name <c><anno>Name</anno></c> with a pid, that is,
Globally notifies all nodes of a new global name in a network
of Erlang nodes.</p>
@@ -188,7 +174,7 @@
of the globally registered names that already exist.
The network is also informed of any global names in newly
connected nodes. If any name clashes are discovered,
- the <c>Resolve</c> function is called. Its purpose is to
+ the <c><anno>Resolve</anno></c> function is called. Its purpose is to
decide which pid is correct. If the function crashes, or
returns anything other than one of the pids, the name is
unregistered. This function is called once for each name
@@ -196,7 +182,7 @@
<p>There are three pre-defined resolve functions:
<c>random_exit_name/3</c>, <c>random_notify_name/3</c>, and
- <c>notify_all_name/3</c>. If no <c>Resolve</c> function is
+ <c>notify_all_name/3</c>. If no <c><anno>Resolve</anno></c> function is
defined, <c>random_exit_name</c> is used. This means that one
of the two registered processes will be selected as correct
while the other is killed.</p>
@@ -225,78 +211,63 @@
</func>
<func>
- <name>registered_names() -> [Name]</name>
+ <name name="registered_names" arity="0"/>
<fsummary>All globally registered names</fsummary>
- <type>
- <v>Name = term()</v>
- </type>
<desc>
<p>Returns a lists of all globally registered names.</p>
</desc>
</func>
<func>
- <name>re_register_name(Name, Pid)</name>
- <name>re_register_name(Name, Pid, Resolve) -> void()</name>
+ <name name="re_register_name" arity="2"/>
+ <name name="re_register_name" arity="3"/>
<fsummary>Atomically re-register a name</fsummary>
- <type>
- <v>Name = term()</v>
- <v>Pid = pid()</v>
- <v>Resolve = fun() or {Module, Function} where</v>
- <v>&nbsp;&nbsp;Resolve(Name, Pid, Pid2) -> Pid | Pid2 | none</v>
- </type>
+ <type name="method"/>
+ <type_desc name="method">{<c>Module</c>, <c>Function</c>}
+ is also allowed
+ </type_desc>
<desc>
- <p>Atomically changes the registered name <c>Name</c> on all
- nodes to refer to <c>Pid</c>.</p>
+ <p>Atomically changes the registered name <c><anno>Name</anno></c> on all
+ nodes to refer to <c><anno>Pid</anno></c>.</p>
- <p>The <c>Resolve</c> function has the same behavior as in
+ <p>The <c><anno>Resolve</anno></c> function has the same behavior as in
<c>register_name/2,3</c>.</p>
</desc>
</func>
<func>
- <name>send(Name, Msg) -> Pid</name>
+ <name name="send" arity="2"/>
<fsummary>Send a message to a globally registered pid</fsummary>
- <type>
- <v>Name = term()</v>
- <v>Msg = term()</v>
- <v>Pid = pid()</v>
- </type>
<desc>
- <p>Sends the message <c>Msg</c> to the pid globally registered
- as <c>Name</c>.</p>
+ <p>Sends the message <c><anno>Msg</anno></c> to the pid globally registered
+ as <c><anno>Name</anno></c>.</p>
- <p>Failure: If <c>Name</c> is not a globally registered
+ <p>Failure: If <c><anno>Name</anno></c> is not a globally registered
name, the calling function will exit with reason
- <c>{badarg, {Name, Msg}}</c>.</p>
+ <c>{badarg, {<anno>Name</anno>, <anno>Msg</anno>}}</c>.</p>
</desc>
</func>
<func>
- <name>set_lock(Id)</name>
- <name>set_lock(Id, Nodes)</name>
- <name>set_lock(Id, Nodes, Retries) -> boolean()</name>
+ <name name="set_lock" arity="1"/>
+ <name name="set_lock" arity="2"/>
+ <name name="set_lock" arity="3"/>
<fsummary>Set a lock on the specified nodes</fsummary>
- <type>
- <v>Id = {ResourceId, LockRequesterId}</v>
- <v>&nbsp;ResourceId = term()</v>
- <v>&nbsp;LockRequesterId = term()</v>
- <v>Nodes = [node()]</v>
- <v>Retries = int() >= 0 | infinity</v>
- </type>
+ <type name="id"/>
+ <type name="retries"/>
<desc>
<p>Sets a lock on the specified nodes (or on all nodes if none
- are specified) on <c>ResourceId</c> for
- <c>LockRequesterId</c>. If a lock already exists on
- <c>ResourceId</c> for another requester than
- <c>LockRequesterId</c>, and <c>Retries</c> is not equal to 0,
+ are specified) on <c><anno>ResourceId</anno></c> for
+ <c><anno>LockRequesterId</anno></c>. If a lock already exists on
+ <c><anno>ResourceId</anno></c> for another requester than
+ <c><anno>LockRequesterId</anno></c>, and <c><anno>Retries</anno></c> is not equal to 0,
the process sleeps for a while and will try to execute
- the action later. When <c>Retries</c> attempts have been made,
+ the action later. When <c><anno>Retries</anno></c> attempts have been made,
<c>false</c> is returned, otherwise <c>true</c>. If
- <c>Retries</c> is <c>infinity</c>, <c>true</c> is eventually
+ <c><anno>Retries</anno></c> is <c>infinity</c>, <c>true</c> is eventually
returned (unless the lock is never released).</p>
- <p>If no value for <c>Retries</c> is given, <c>infinity</c> is
+ <p>If no value for <c><anno>Retries</anno></c> is given, <c>infinity</c> is
used.</p>
<p>This function is completely synchronous.</p>
@@ -315,7 +286,7 @@
application to detect and rectify a deadlock.</p>
<note>
- <p>Some values of <c>ResourceId</c> should be avoided or
+ <p>Some values of <c><anno>ResourceId</anno></c> should be avoided or
Erlang/OTP will not work properly. A list of resources to
avoid: <c>global</c>, <c>dist_ac</c>,
<c>mnesia_table_lock</c>, <c>mnesia_adjust_log_writes</c>,
@@ -326,7 +297,7 @@
</func>
<func>
- <name>sync() -> void()</name>
+ <name name="sync" arity="0"/>
<fsummary>Synchronize the global name server</fsummary>
<desc>
<p>Synchronizes the global name server with all nodes known to
@@ -335,56 +306,45 @@
the global name server will receive global information from
all nodes. This function can be called when new nodes are
added to the network.</p>
+ <p>The only possible error reason <c>Reason</c> is
+ <c>{"global_groups definition error", Error}</c>.</p>
</desc>
</func>
<func>
- <name>trans(Id, Fun)</name>
- <name>trans(Id, Fun, Nodes)</name>
- <name>trans(Id, Fun, Nodes, Retries) -> Res | aborted</name>
+ <name name="trans" arity="2"/>
+ <name name="trans" arity="3"/>
+ <name name="trans" arity="4"/>
<fsummary>Micro transaction facility</fsummary>
- <type>
- <v>Id = {ResourceId, LockRequesterId}</v>
- <v>&nbsp;ResourceId = term()</v>
- <v>&nbsp;LockRequesterId = term()</v>
- <v>Fun = fun() | {M, F}</v>
- <v>Nodes = [node()]</v>
- <v>Retries = int() >= 0 | infinity</v>
- <v>Res = term()</v>
- </type>
+ <type name="retries"/>
+ <type name="trans_fun"/>
<desc>
- <p>Sets a lock on <c>Id</c> (using <c>set_lock/3</c>). If this
- succeeds, <c>Fun()</c> is evaluated and the result <c>Res</c>
+ <p>Sets a lock on <c><anno>Id</anno></c> (using <c>set_lock/3</c>). If this
+ succeeds, <c><anno>Fun</anno>()</c> is evaluated and the result <c><anno>Res</anno></c>
is returned. Returns <c>aborted</c> if the lock attempt
- failed. If <c>Retries</c> is set to <c>infinity</c>,
+ failed. If <c><anno>Retries</anno></c> is set to <c>infinity</c>,
the transaction will not abort.</p>
<p><c>infinity</c> is the default setting and will be used if
- no value is given for <c>Retries</c>.</p>
+ no value is given for <c><anno>Retries</anno></c>.</p>
</desc>
</func>
<func>
- <name>unregister_name(Name) -> void()</name>
+ <name name="unregister_name" arity="1"/>
<fsummary>Remove a globally registered name for a pid</fsummary>
- <type>
- <v>Name = term()</v>
- </type>
<desc>
- <p>Removes the globally registered name <c>Name</c> from
+ <p>Removes the globally registered name <c><anno>Name</anno></c> from
the network of Erlang nodes.</p>
</desc>
</func>
<func>
- <name>whereis_name(Name) -> pid() | undefined</name>
+ <name name="whereis_name" arity="1"/>
<fsummary>Get the pid with a given globally registered name</fsummary>
- <type>
- <v>Name = term()</v>
- </type>
<desc>
<p>Returns the pid with the globally registered name
- <c>Name</c>. Returns <c>undefined</c> if the name is not
+ <c><anno>Name</anno></c>. Returns <c>undefined</c> if the name is not
globally registered.</p>
</desc>
</func>
diff --git a/lib/kernel/doc/src/global_group.xml b/lib/kernel/doc/src/global_group.xml
index 4facf4a4aa..abf6178fc4 100644
--- a/lib/kernel/doc/src/global_group.xml
+++ b/lib/kernel/doc/src/global_group.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1998</year><year>2009</year>
+ <year>1998</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -42,26 +42,7 @@
<seealso marker="kernel_app">kernel(6)</seealso>,
<seealso marker="config">config(4)</seealso>:</p>
<code type="none">
-{global_groups, [GroupTuple]}</code>
- <p>Types:</p>
- <list type="bulleted">
- <item><c>GroupTuple = {GroupName, [Node]} | {GroupName, PublishType, [Node]}</c></item>
- <item><c>GroupName = atom()</c> (naming a global group)</item>
- <item><c>PublishType = normal | hidden</c></item>
- <item><c>Node = atom()</c> (naming a node)</item>
- </list>
- <p>A <c>GroupTuple</c> without <c>PublishType</c> is the same as a
- <c>GroupTuple</c> with <c>PublishType == normal</c>.</p>
- <p>A node started with the command line flag <c>-hidden</c>, see
- <seealso marker="erts:erl">erl(1)</seealso>, is said to be a
- <em>hidden</em> node. A hidden node will establish hidden
- connections to nodes not part of the same global group, but
- normal (visible) connections to nodes part of the same global
- group.</p>
- <p>A global group defined with <c>PublishType == hidden</c>, is
- said to be a hidden global group. All nodes in a hidden global
- group are hidden nodes, regardless if they are started with
- the <c>-hidden</c> command line flag or not.</p>
+{global_groups, [GroupTuple :: group_tuple()]}</code>
<p>For the processes and nodes to run smoothly using the global
group functionality, the following criteria must be met:</p>
<list type="bulleted">
@@ -82,14 +63,44 @@
<p>In the following description, a <em>group node</em> is a node
belonging to the same global group as the local node.</p>
</description>
+ <datatypes>
+ <datatype>
+ <name name="group_tuple"/>
+ <desc>
+ <p>A <c>GroupTuple</c> without <c>PublishType</c> is the same as a
+ <c>GroupTuple</c> with <c>PublishType == normal</c>.</p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="group_name"/>
+ </datatype>
+ <datatype>
+ <name name="publish_type"/>
+ <desc>
+ <p>A node started with the command line flag <c>-hidden</c>, see
+ <seealso marker="erts:erl">erl(1)</seealso>, is said to be a
+ <em>hidden</em> node. A hidden node will establish hidden
+ connections to nodes not part of the same global group, but
+ normal (visible) connections to nodes part of the same global
+ group.</p>
+ <p>A global group defined with <c>PublishType == hidden</c>, is
+ said to be a hidden global group. All nodes in a hidden global
+ group are hidden nodes, regardless if they are started with
+ the <c>-hidden</c> command line flag or not.</p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="name"/>
+ <desc><p>A registered name.</p></desc>
+ </datatype>
+ <datatype>
+ <name name="where"/>
+ </datatype>
+ </datatypes>
<funcs>
<func>
- <name>global_groups() -> {GroupName, GroupNames} | undefined</name>
+ <name name="global_groups" arity="0"/>
<fsummary>Return the global group names</fsummary>
- <type>
- <v>GroupName = atom()</v>
- <v>GroupNames = [GroupName]</v>
- </type>
<desc>
<p>Returns a tuple containing the name of the global group
the local node belongs to, and the list of all other known
@@ -98,53 +109,52 @@
</desc>
</func>
<func>
- <name>info() -> [{Item, Info}]</name>
+ <name name="info" arity="0"/>
<fsummary>Information about global groups</fsummary>
- <type>
- <v>Item, Info -- see below</v>
- </type>
+ <type name="info_item"/>
+ <type name="sync_state"/>
<desc>
<p>Returns a list containing information about the global
groups. Each element of the list is a tuple. The order of
the tuples is not defined.</p>
<taglist>
- <tag><c>{state, State}</c></tag>
+ <tag><c>{state, <anno>State</anno>}</c></tag>
<item>
<p>If the local node is part of a global group,
- <c>State == synced</c>. If no global groups are defined,
- <c>State == no_conf</c>.</p>
+ <c><anno>State</anno> == synced</c>. If no global groups are defined,
+ <c><anno>State</anno> == no_conf</c>.</p>
</item>
- <tag><c>{own_group_name, GroupName}</c></tag>
+ <tag><c>{own_group_name, <anno>GroupName</anno>}</c></tag>
<item>
<p>The name (atom) of the group that the local node belongs
to.</p>
</item>
- <tag><c>{own_group_nodes, Nodes}</c></tag>
+ <tag><c>{own_group_nodes, <anno>Nodes</anno>}</c></tag>
<item>
<p>A list of node names (atoms), the group nodes.</p>
</item>
- <tag><c>{synced_nodes, Nodes}</c></tag>
+ <tag><c>{synced_nodes, <anno>Nodes</anno>}</c></tag>
<item>
<p>A list of node names, the group nodes currently
synchronized with the local node.</p>
</item>
- <tag><c>{sync_error, Nodes}</c></tag>
+ <tag><c>{sync_error, <anno>Nodes</anno>}</c></tag>
<item>
<p>A list of node names, the group nodes with which
the local node has failed to synchronize.</p>
</item>
- <tag><c>{no_contact, Nodes}</c></tag>
+ <tag><c>{no_contact, <anno>Nodes</anno>}</c></tag>
<item>
<p>A list of node names, the group nodes to which there are
currently no connections.</p>
</item>
- <tag><c>{other_groups, Groups}</c></tag>
+ <tag><c>{other_groups, <anno>Groups</anno>}</c></tag>
<item>
- <p><c>Groups</c> is a list of tuples
- <c>{GroupName, Nodes}</c>, specifying the name and nodes
+ <p><c><anno>Groups</anno></c> is a list of tuples
+ <c>{<anno>GroupName</anno>, <anno>Nodes</anno>}</c>, specifying the name and nodes
of the other global groups.</p>
</item>
- <tag><c>{monitoring, Pids}</c></tag>
+ <tag><c>{monitoring, <anno>Pids</anno>}</c></tag>
<item>
<p>A list of pids, specifying the processes which have
subscribed to <c>nodeup</c> and <c>nodedown</c> messages.</p>
@@ -153,73 +163,52 @@
</desc>
</func>
<func>
- <name>monitor_nodes(Flag) -> ok </name>
+ <name name="monitor_nodes" arity="1"/>
<fsummary>Subscribe to node status changes</fsummary>
- <type>
- <v>Flag = bool()</v>
- </type>
<desc>
- <p>Depending on <c>Flag</c>, the calling process starts
- subscribing (<c>Flag == true</c>) or stops subscribing
- (<c>Flag == false</c>) to node status change messages.</p>
+ <p>Depending on <c><anno>Flag</anno></c>, the calling process starts
+ subscribing (<c><anno>Flag</anno> == true</c>) or stops subscribing
+ (<c><anno>Flag</anno> == false</c>) to node status change messages.</p>
<p>A process which has subscribed will receive the messages
<c>{nodeup, Node}</c> and <c>{nodedown, Node}</c> when a
group node connects or disconnects, respectively.</p>
</desc>
</func>
<func>
- <name>own_nodes() -> Nodes</name>
+ <name name="own_nodes" arity="0"/>
<fsummary>Return the group nodes</fsummary>
- <type>
- <v>Nodes = [Node]</v>
- <v>&nbsp;Node = node()</v>
- </type>
<desc>
<p>Returns the names of all group nodes, regardless of their
current status.</p>
</desc>
</func>
<func>
- <name>registered_names(Where) -> Names</name>
+ <name name="registered_names" arity="1"/>
<fsummary>Return globally registered names</fsummary>
- <type>
- <v>Where = {node, Node} | {group, GroupName}</v>
- <v>&nbsp;Node = node()</v>
- <v>&nbsp;GroupName = atom()</v>
- <v>Names = [Name]</v>
- <v>&nbsp;Name = atom()</v>
- </type>
<desc>
<p>Returns a list of all names which are globally registered
on the specified node or in the specified global group.</p>
</desc>
</func>
<func>
- <name>send(Name, Msg) -> pid() | {badarg, {Name, Msg}}</name>
- <name>send(Where, Name, Msg) -> pid() | {badarg, {Name, Msg}}</name>
+ <name name="send" arity="2"/>
+ <name name="send" arity="3"/>
<fsummary>Send a message to a globally registered pid</fsummary>
- <type>
- <v>Where = {node, Node} | {group, GroupName}</v>
- <v>&nbsp;Node = node()</v>
- <v>&nbsp;GroupName = atom()</v>
- <v>Name = atom()</v>
- <v>Msg = term()</v>
- </type>
<desc>
- <p>Searches for <c>Name</c>, globally registered on
+ <p>Searches for <c><anno>Name</anno></c>, globally registered on
the specified node or in the specified global group, or --
- if the <c>Where</c> argument is not provided -- in any global
+ if the <c><anno>Where</anno></c> argument is not provided -- in any global
group. The global groups are searched in the order in which
they appear in the value of the <c>global_groups</c>
configuration parameter.</p>
- <p>If <c>Name</c> is found, the message <c>Msg</c> is sent to
+ <p>If <c><anno>Name</anno></c> is found, the message <c><anno>Msg</anno></c> is sent to
the corresponding pid. The pid is also the return value of
the function. If the name is not found, the function returns
- <c>{badarg, {Name, Msg}}</c>.</p>
+ <c>{badarg, {<anno>Name</anno>, <anno>Msg</anno>}}</c>.</p>
</desc>
</func>
<func>
- <name>sync() -> ok</name>
+ <name name="sync" arity="0"/>
<fsummary>Synchronize the group nodes</fsummary>
<desc>
<p>Synchronizes the group nodes, that is, the global name
@@ -235,23 +224,17 @@
</desc>
</func>
<func>
- <name>whereis_name(Name) -> pid() | undefined</name>
- <name>whereis_name(Where, Name) -> pid() | undefined</name>
+ <name name="whereis_name" arity="1"/>
+ <name name="whereis_name" arity="2"/>
<fsummary>Get the pid with a given globally registered name</fsummary>
- <type>
- <v>Where = {node, Node} | {group, GroupName}</v>
- <v>&nbsp;Node = node()</v>
- <v>&nbsp;GroupName = atom()</v>
- <v>Name = atom()</v>
- </type>
<desc>
- <p>Searches for <c>Name</c>, globally registered on
+ <p>Searches for <c><anno>Name</anno></c>, globally registered on
the specified node or in the specified global group, or -- if
- the <c>Where</c> argument is not provided -- in any global
+ the <c><anno>Where</anno></c> argument is not provided -- in any global
group. The global groups are searched in the order in which
they appear in the value of the <c>global_groups</c>
configuration parameter.</p>
- <p>If <c>Name</c> is found, the corresponding pid is returned.
+ <p>If <c><anno>Name</anno></c> is found, the corresponding pid is returned.
If the name is not found, the function returns
<c>undefined</c>.</p>
</desc>
diff --git a/lib/kernel/doc/src/heart.xml b/lib/kernel/doc/src/heart.xml
index 0df699572d..e2dbcbe63d 100644
--- a/lib/kernel/doc/src/heart.xml
+++ b/lib/kernel/doc/src/heart.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2009</year>
+ <year>1996</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -76,11 +76,8 @@
</description>
<funcs>
<func>
- <name>set_cmd(Cmd) -> ok | {error, {bad_cmd, Cmd}}</name>
+ <name name="set_cmd" arity="1"/>
<fsummary>Set a temporary reboot command</fsummary>
- <type>
- <v>Cmd = string()</v>
- </type>
<desc>
<p>Sets a temporary reboot command. This command is used if
a <c>HEART_COMMAND</c> other than the one specified with
@@ -88,12 +85,12 @@
the system. The new Erlang runtime system will (if it
misbehaves) use the environment variable
<c>HEART_COMMAND</c> to reboot.</p>
- <p>Limitations: The length of the <c>Cmd</c> command string
+ <p>Limitations: The length of the <c><anno>Cmd</anno></c> command string
must be less than 2047 characters.</p>
</desc>
</func>
<func>
- <name>clear_cmd() -> ok</name>
+ <name name="clear_cmd" arity="0"/>
<fsummary>Clear the temporary boot command</fsummary>
<desc>
<p>Clears the temporary boot command. If the system terminates,
@@ -101,11 +98,8 @@
</desc>
</func>
<func>
- <name>get_cmd() -> {ok, Cmd}</name>
+ <name name="get_cmd" arity="0"/>
<fsummary>Get the temporary reboot command</fsummary>
- <type>
- <v>Cmd = string()</v>
- </type>
<desc>
<p>Get the temporary reboot command. If the command is cleared,
the empty string will be returned.</p>
diff --git a/lib/kernel/doc/src/inet.xml b/lib/kernel/doc/src/inet.xml
index f05a224f33..fd843b00d9 100644
--- a/lib/kernel/doc/src/inet.xml
+++ b/lib/kernel/doc/src/inet.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1997</year><year>2010</year>
+ <year>1997</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -54,33 +54,6 @@ $ <input>erl -sname test -kernel \</input>
<input>inet_default_listen_options '[{delay_send,true}]'</input></pre>
<p>Note that the default option <c>{active, true}</c> currently
cannot be changed, for internal reasons.</p>
- </description>
-
- <section>
- <title>DATA TYPES</title>
- <code type="none">
-#hostent{h_addr_list = [ip_address()] % list of addresses for this host
- h_addrtype = inet | inet6
- h_aliases = [hostname()] % list of aliases
- h_length = int() % length of address in bytes
- h_name = hostname() % official name for host
- The record is defined in the Kernel include file "inet.hrl"
- Add the following directive to the module:
- -include_lib("kernel/include/inet.hrl").
-
-hostname() = atom() | string()
-
-ip_address() = {N1,N2,N3,N4} % IPv4
- | {K1,K2,K3,K4,K5,K6,K7,K8} % IPv6
- Ni = 0..255
- Ki = 0..65535
-
-posix()
- an atom which is named from the Posix error codes used in
- Unix, and in the runtime libraries of most C compilers
-
-socket()
- see gen_tcp(3), gen_udp(3)</code>
<p>Addresses as inputs to functions can be either a string or a
tuple. For instance, the IP address 150.236.20.73 can be passed to
<c>gethostbyaddr/1</c> either as the string "150.236.20.73"
@@ -109,24 +82,58 @@ fe80::204:acff:fe17:bf38
{ok,{192,168,42,2}}
2> <input>inet_parse:address("FFFF::192.168.42.2").</input>
{ok,{65535,0,0,0,0,0,49320,10754}}</pre>
- </section>
+ </description>
+
+ <datatypes>
+ <datatype>
+ <name name="hostent"/>
+ <desc>
+ <p>The record is defined in the Kernel include file "inet.hrl".
+ Add the following directive to the module:</p>
+<code>-include_lib("kernel/include/inet.hrl").</code></desc>
+ </datatype>
+ <datatype>
+ <name name="hostname"/>
+ </datatype>
+ <datatype>
+ <name name="ip_address"/>
+ </datatype>
+ <datatype>
+ <name name="ip4_address"/>
+ </datatype>
+ <datatype>
+ <name name="ip6_address"/>
+ </datatype>
+ <datatype>
+ <name name="posix"/>
+ <desc><p>An atom which is named from the Posix error codes
+ used in Unix, and in the runtime libraries of most
+ C compilers. See
+ <seealso marker="#error_codes">POSIX Error Codes</seealso>.</p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name><marker id="type-socket">socket()</marker></name>
+ <desc><p>See <seealso marker="gen_tcp#type-socket">gen_tcp(3)</seealso>
+ and <seealso marker="gen_udp#type-socket">gen_udp(3)</seealso>.</p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="family_option"/>
+ </datatype>
+ </datatypes>
+
<funcs>
<func>
- <name>close(Socket) -> ok</name>
+ <name name="close" arity="1"/>
<fsummary>Close a socket of any type</fsummary>
- <type>
- <v>Socket = socket()</v>
- </type>
<desc>
<p>Closes a socket of any type.</p>
</desc>
</func>
<func>
- <name>get_rc() -> [{Par, Val}]</name>
+ <name name="get_rc" arity="0"/>
<fsummary>Return a list of IP configuration parameters</fsummary>
- <type>
- <v>Par, Val -- see below</v>
- </type>
<desc>
<p>Returns the state of the Inet configuration database in
form of a list of recorded configuration parameters. (See the
@@ -135,116 +142,74 @@ fe80::204:acff:fe17:bf38
</desc>
</func>
<func>
- <name>format_error(Posix) -> string()</name>
+ <name name="format_error" arity="1"/>
<fsummary>Return a descriptive string for an error reason</fsummary>
- <type>
- <v>Posix = posix()</v>
- </type>
<desc>
<p>Returns a diagnostic error string. See the section below
- for possible <c>Posix</c> values and the corresponding
+ for possible <c><anno>Posix</anno></c> values and the corresponding
strings.</p>
</desc>
</func>
<func>
- <name>getaddr(Host, Family) -> {ok, Address} | {error, posix()}</name>
+ <name name="getaddr" arity="2"/>
<fsummary>Return the IP-address for a host</fsummary>
- <type>
- <v>Host = ip_address() | string() | atom()</v>
- <v>Family = inet | inet6</v>
- <v>Address = ip_address()</v>
- <v>posix() = term()</v>
- </type>
<desc>
- <p>Returns the IP-address for <c>Host</c> as a tuple of
- integers. <c>Host</c> can be an IP-address, a single hostname
+ <p>Returns the IP-address for <c><anno>Host</anno></c> as a tuple of
+ integers. <c><anno>Host</anno></c> can be an IP-address, a single hostname
or a fully qualified hostname.</p>
</desc>
</func>
<func>
- <name>getaddrs(Host, Family) -> {ok, Addresses} | {error, posix()}</name>
+ <name name="getaddrs" arity="2"/>
<fsummary>Return the IP-addresses for a host</fsummary>
- <type>
- <v>Host = ip_address() | string() | atom()</v>
- <v>Addresses = [ip_address()]</v>
- <v>Family = inet | inet6</v>
- </type>
<desc>
- <p>Returns a list of all IP-addresses for <c>Host</c>.
- <c>Host</c> can be an IP-address, a single hostname or a fully
+ <p>Returns a list of all IP-addresses for <c><anno>Host</anno></c>.
+ <c><anno>Host</anno></c> can be an IP-address, a single hostname or a fully
qualified hostname.</p>
</desc>
</func>
<func>
- <name>gethostbyaddr(Address) -> {ok, Hostent} | {error, posix()}</name>
+ <name name="gethostbyaddr" arity="1"/>
<fsummary>Return a hostent record for the host with the given address</fsummary>
- <type>
- <v>Address = string() | ip_address()</v>
- <v>Hostent = #hostent{}</v>
- </type>
<desc>
<p>Returns a <c>hostent</c> record given an address.</p>
</desc>
</func>
<func>
- <name>gethostbyname(Name) -> {ok, Hostent} | {error, posix()}</name>
+ <name name="gethostbyname" arity="1"/>
<fsummary>Return a hostent record for the host with the given name</fsummary>
- <type>
- <v>Hostname = hostname()</v>
- <v>Hostent = #hostent{}</v>
- </type>
<desc>
<p>Returns a <c>hostent</c> record given a hostname.</p>
</desc>
</func>
<func>
- <name>gethostbyname(Name, Family) -> {ok, Hostent} | {error, posix()}</name>
+ <name name="gethostbyname" arity="2"/>
<fsummary>Return a hostent record for the host with the given name</fsummary>
- <type>
- <v>Hostname = hostname()</v>
- <v>Family = inet | inet6</v>
- <v>Hostent = #hostent{}</v>
- </type>
<desc>
<p>Returns a <c>hostent</c> record given a hostname, restricted
to the given address family.</p>
</desc>
</func>
<func>
- <name>gethostname() -> {ok, Hostname}</name>
+ <name name="gethostname" arity="0"/>
<fsummary>Return the local hostname</fsummary>
- <type>
- <v>Hostname = string()</v>
- </type>
<desc>
<p>Returns the local hostname. Will never fail.</p>
</desc>
</func>
<func>
- <name>getifaddrs() -> {ok,Iflist} | {error,posix}</name>
+ <name name="getifaddrs" arity="0"/>
<fsummary>Return a list of interfaces and their addresses</fsummary>
- <type>
- <v>Iflist = {Ifname,[Ifopt]}</v>
- <v>Ifname = string()</v>
- <v>Ifopt = {flag,[Flag]} | {addr,Addr} | {netmask,Netmask}
- | {broadaddr,Broadaddr} | {dstaddr,Dstaddr}
- | {hwaddr,Hwaddr}</v>
- <v>Flag = up | broadcast | loopback | pointtopoint
- | running | multicast</v>
- <v>Addr = Netmask = Broadadddr = Dstaddr = ip_address()</v>
- <v>Hwaddr = [byte()]</v>
- </type>
- </func>
<desc>
<p>
Returns a list of 2-tuples containing interface names and the
- interface's addresses. <c>Ifname</c> is a Unicode string.
- <c>Hwaddr</c> is hardware dependent, e.g on Ethernet interfaces
+ interface's addresses. <c><anno>Ifname</anno></c> is a Unicode string.
+ <c><anno>Hwaddr</anno></c> is hardware dependent, e.g on Ethernet interfaces
it is the 6-byte Ethernet address (MAC address (EUI-48 address)).
</p>
<p>
- The <c>{addr,Addr}</c>, <c>{netmask,_}</c> and <c>{broadaddr,_}</c>
+ The <c>{addr,<anno>Addr</anno>}</c>, <c>{netmask,_}</c> and <c>{broadaddr,_}</c>
tuples are repeated in the result list iff the interface has multiple
addresses. If you come across an interface that has
multiple <c>{flag,_}</c> or <c>{hwaddr,_}</c> tuples you have
@@ -252,8 +217,8 @@ fe80::204:acff:fe17:bf38
The <c>{flag,_}</c> tuple is mandatory, all other optional.
</p>
<p>
- Do not rely too much on the order of <c>Flag</c> atoms or
- <c>Ifopt</c> tuples. There are some rules, though:
+ Do not rely too much on the order of <c><anno>Flag</anno></c> atoms or
+ <c><anno>Ifopt</anno></c> tuples. There are some rules, though:
<list>
<item>
Immediately after <c>{addr,_}</c> follows <c>{netmask,_}</c>
@@ -261,7 +226,7 @@ fe80::204:acff:fe17:bf38
<item>
Immediately thereafter follows <c>{broadaddr,_}</c> if
the <c>broadcast</c> flag is <em>not</em> set and the
- <c>pointtopoint</c>flag <em>is</em> set.
+ <c>pointtopoint</c> flag <em>is</em> set.
</item>
<item>
Any <c>{netmask,_}</c>, <c>{broadaddr,_}</c> or
@@ -277,11 +242,12 @@ fe80::204:acff:fe17:bf38
</p>
<p>
On Windows, the data is fetched from quite different OS API
- functions, so the <c>Netmask</c> and <c>Broadaddr</c>
- values may be calculated, just as some <c>Flag</c> values.
+ functions, so the <c><anno>Netmask</anno></c> and <c><anno>Broadaddr</anno></c>
+ values may be calculated, just as some <c><anno>Flag</anno></c> values.
You have been warned. Report flagrant bugs.
</p>
</desc>
+ </func>
<func>
<name>getopts(Socket, Options) -> {ok, OptionValues} | {error, posix()}</name>
@@ -291,13 +257,14 @@ fe80::204:acff:fe17:bf38
<v>Options = [Opt | RawOptReq]</v>
<v>Opt = atom()</v>
<v>RawOptReq = {raw, Protocol, OptionNum, ValueSpec}</v>
- <v>Protocol = int()</v>
- <v>OptionNum = int()</v>
+ <v>Protocol = integer()</v>
+ <v>OptionNum = integer()</v>
<v>ValueSpec = ValueSize | ValueBin</v>
- <v>ValueSize = int()</v>
+ <v>ValueSize = integer()</v>
<v>ValueBin = binary()</v>
<v>OptionValues = [{Opt, Val} | {raw, Protocol, OptionNum, ValueBin}]</v>
</type>
+ <type name="socket_getopt"/>
<desc>
<p>Gets one or more options for a socket.
See <seealso marker="#setopts/2">setopts/2</seealso>
@@ -419,13 +386,8 @@ fe80::204:acff:fe17:bf38
</func>
<func>
- <name>peername(Socket) -> {ok, {Address, Port}} | {error, posix()}</name>
+ <name name="peername" arity="1"/>
<fsummary>Return the address and port for the other end of a connection</fsummary>
- <type>
- <v>Socket = socket()</v>
- <v>Address = ip_address()</v>
- <v>Port = int()</v>
- </type>
<desc>
<p>Returns the address and port for the other end of a
connection.</p>
@@ -436,20 +398,15 @@ fe80::204:acff:fe17:bf38
<fsummary>Return the local port number for a socket</fsummary>
<type>
<v>Socket = socket()</v>
- <v>Port = int()</v>
+ <v>Port = integer()</v>
</type>
<desc>
<p>Returns the local port number for a socket.</p>
</desc>
</func>
<func>
- <name>sockname(Socket) -> {ok, {Address, Port}} | {error, posix()}</name>
+ <name name="sockname" arity="1"/>
<fsummary>Return the local address and port number for a socket</fsummary>
- <type>
- <v>Socket = socket()</v>
- <v>Address = ip_address()</v>
- <v>Port = int()</v>
- </type>
<desc>
<p>Returns the local address and port number for a socket.</p>
</desc>
@@ -460,8 +417,8 @@ fe80::204:acff:fe17:bf38
<type>
<v>Socket = term()</v>
<v>Options = [{Opt, Val} | {raw, Protocol, Option, ValueBin}]</v>
- <v>Protocol = int()</v>
- <v>OptionNum = int()</v>
+ <v>Protocol = integer()</v>
+ <v>OptionNum = integer()</v>
<v>ValueBin = binary()</v>
<v>&nbsp;Opt, Val -- see below</v>
</type>
diff --git a/lib/kernel/doc/src/inet_res.xml b/lib/kernel/doc/src/inet_res.xml
index d8fe23544b..bf73ccf13d 100644
--- a/lib/kernel/doc/src/inet_res.xml
+++ b/lib/kernel/doc/src/inet_res.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2009</year><year>2009</year>
+ <year>2009</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -76,64 +76,38 @@
query is tried for the <c>alt_nameservers</c>.</p>
</section>
-
-
-
- <section>
- <title>DATA TYPES</title>
- <p>As defined in the module
- <seealso marker="kernel:inet">inet</seealso>:</p>
- <code type="none">
-hostent() = #hostent{}
-posix() = some atom()s
-ip_address() = tuple of integers of arity 4 or 8</code>
-
+ <datatypes>
<p>Resolver types:</p>
- <code type="none">These correspond to resolver options:
-
-res_option() =
- [ {alt_nameservers, [ nameserver() ]}
- | {edns, 0 | false} % Use EDNS
- | {inet6, bool()} % Return IPv6 addresses
- | {nameservers, [ nameserver() ]} % List of nameservers
- | {recurse, bool()} % Request server recursion
- | {retry, integer()} % UDP retries
- | {timeout, integer()} % UDP query timeout
- | {udp_payload_size, integer()} % EDNS payload size
- | {usevc, bool()} ] % Use TCP (Virtual Circuit)
-
-nameserver() = {ip_address(),Port}
- Port = integer(1..65535)
-
-res_error() =
- formerr |
- qfmterror |
- servfail |
- nxdomain |
- notimp |
- refused |
- badvers |
- timeout
-</code>
-
- <p>DNS types:</p>
- <marker id="dns_types"/>
- <code type="none">dns_name() = string() with no adjacent dots
-
-rr_type() = a | aaaa | cname | gid | hinfo | ns | mb | md | mg | mf
- | minfo | mx | naptr | null | ptr | soa | spf | srv | txt
- | uid | uinfo | unspec | wks
-
-query_type() = axfr | mailb | maila | any | rr_type()
-
-dns_class() = in | chaos | hs | any
-
+ <datatype>
+ <name name="res_option"/>
+ </datatype>
+ <datatype>
+ <name name="nameserver"/>
+ </datatype>
+ <datatype>
+ <name name="res_error"/>
+ </datatype>
+
+ <p><marker id="dns_types"/>DNS types:</p>
+ <datatype>
+ <name name="dns_name"/>
+ <desc><p>A string with no adjacent dots.</p></desc>
+ </datatype>
+ <datatype>
+ <name name="rr_type"/>
+ </datatype>
+ <datatype>
+ <name name="dns_class"/>
+ </datatype>
+ <datatype>
+ <name name="dns_msg"/>
+ <desc>
+ <p>This is the start of a hiearchy of opaque data structures
+ that can be examined with access functions in inet_dns that
+ return lists of {Field,Value} tuples. The arity 2 functions
+ just return the value for a given field.
+<pre>
dns_msg() = DnsMsg
- This is the start of a hiearchy of opaque data structures
- that can be examined with access functions in inet_dns
- that return lists of {Field,Value} tuples. The arity 2
- functions just return the value for a given field.
-
inet_dns:msg(DnsMsg) ->
[ {header, dns_header()}
| {qdlist, dns_query()}
@@ -143,19 +117,21 @@ dns_msg() = DnsMsg
inet_dns:msg(DnsMsg, header) -> dns_header() % for example
inet_dns:msg(DnsMsg, Field) -> Value
-dhs_header() = DnsHeader
+dns_header() = DnsHeader
inet_dns:header(DnsHeader) ->
[ {id, integer()}
- | {qr, bool()}
+ | {qr, boolean()}
| {opcode, 'query' | iquery | status | integer()}
- | {aa, bool()}
- | {tc, bool()}
- | {rd, bool()}
- | {ra, bool()}
- | {pr, bool()}
+ | {aa, boolean()}
+ | {tc, boolean()}
+ | {rd, boolean()}
+ | {ra, boolean()}
+ | {pr, boolean()}
| {rcode, integer(0..16)} ]
inet_dns:header(DnsHeader, Field) -> Value
+query_type() = axfr | mailb | maila | any | rr_type()
+
dns_query() = DnsQuery
inet_dns:dns_query(DnsQuery) ->
[ {domain, dns_name()}
@@ -179,32 +155,6 @@ dns_rr() = DnsRr
| {data, dns_data()} ]
inet_dns:rr(DnsRr, Field) -> Value
-dns_data() = % for dns_type()
- [ dns_name() % ns, md, mf, cname, mb, mg, mr, ptr
- | ip_address(v4) % a
- | ip_address(v6) % aaaa
- | {MName,RName,Serial,Refresh,Retry,Expiry,Minimum} % soa
- | {ip_address(v4),Proto,BitMap} % wks
- | {CpuString,OsString} % hinfo
- | {RM,EM} % minfo
- | {Prio,dns_name()} % mx
- | {Prio,Weight,Port,dns_name()} % srv
- | {Order,Preference,Flags,Services,Regexp,dns_name()} % naptr
- | [ string() ] % txt, spf
- | binary() ] % null, integer()
-MName, RName = dns_name()
-Serial, Refresh, Retry, Expiry, Minimum = integer(),
-Proto = integer()
-BitMap = binary()
-CpuString, OsString = string()
-RM = EM = dns_name()
-Prio, Weight, Port = integer()
-Order, Preference = integer()
-Flags, Services = string(),
-Regexp = string(utf8)
-
-
-
There is an info function for the types above:
inet_dns:record_type(dns_msg()) -> msg;
@@ -214,26 +164,25 @@ inet_dns:record_type(dns_rr()) -> rr;
inet_dns:record_type(_) -> undefined.
So; inet_dns:(inet_dns:record_type(X))(X) will convert
-any of these data structures into a {Field,Value} list.</code>
- </section>
-
+any of these data structures into a {Field,Value} list.</pre></p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="dns_data"/>
+ <desc><p><c><anno>Regexp</anno></c> is a string with characters encoded in the
+ UTF-8 coding standard.</p>
+ </desc>
+ </datatype>
+ </datatypes>
<funcs>
<func>
- <name>getbyname(Name, Type) -> {ok,hostent()} | {error,Reason}</name>
- <name>getbyname(Name, Type, Timeout) ->
- {ok,hostent()} | {error,Reason}
- </name>
+ <name name="getbyname" arity="2"/>
+ <name name="getbyname" arity="3"/>
<fsummary>Resolve a DNS record of the given type for the given host
</fsummary>
- <type>
- <v>Name = dns_name()</v>
- <v>Type = rr_type()</v>
- <v>Timeout = integer() >= 0 | infinity</v>
- <v>Reason = posix() | res_error()</v>
- </type>
<desc>
<p>Resolve a DNS record of the given type for the given host,
of class <c>in</c>. On success returns a <c>hostent()</c> record with
@@ -252,17 +201,10 @@ any of these data structures into a {Field,Value} list.</code>
</func>
<func>
- <name>gethostbyaddr(Address) -> {ok,hostent()} | {error,Reason}</name>
- <name>gethostbyaddr(Address, Timeout) ->
- {ok,hostent()} | {error,Reason}
- </name>
+ <name name="gethostbyaddr" arity="1"/>
+ <name name="gethostbyaddr" arity="2"/>
<fsummary>Return a hostent record for the host with the given address
</fsummary>
- <type>
- <v>Address = ip_address()</v>
- <v>Timeout = integer() >= 0 | infinity</v>
- <v>Reason = posix() | res_error()</v>
- </type>
<desc>
<p>Backend functions used by
<seealso marker="kernel:inet#gethostbyaddr/1">
@@ -273,20 +215,11 @@ any of these data structures into a {Field,Value} list.</code>
</func>
<func>
- <name>gethostbyname(Name) -> {ok,hostent()} | Reason}</name>
- <name>gethostbyname(Name, Family) ->
- {ok,hostent()} | {error,Reason}}
- </name>
- <name>gethostbyname(Name, Family, Timeout) ->
- {ok,hostent()} | {error,Reason}
- </name>
+ <name name="gethostbyname" arity="1"/>
+ <name name="gethostbyname" arity="2"/>
+ <name name="gethostbyname" arity="3"/>
<fsummary>Return a hostent record for the host with the given name
</fsummary>
- <type>
- <v>Name = dns_name()</v>
- <v>Timeout = integer() >= 0 | infinity</v>
- <v>Reason = posix() | res_error()</v>
- </type>
<desc>
<p>Backend functions used by
<seealso marker="kernel:inet#gethostbyname/1">
@@ -305,26 +238,16 @@ any of these data structures into a {Field,Value} list.</code>
</func>
<func>
- <name>lookup(Name, Class, Type) -> [ dns_data() ]
- </name>
- <name>lookup(Name, Class, Type, Opts) -> [ dns_data() ]
- </name>
- <name>lookup(Name, Class, Type, Opts, Timeout) -> [ dns_data() ]
- </name>
+ <name name="lookup" arity="3"/>
+ <name name="lookup" arity="4"/>
+ <name name="lookup" arity="5"/>
<fsummary>Resolve the DNS data for the record of the given type and class
for the given name
</fsummary>
- <type>
- <v>Name = dns_name() | ip_address()</v>
- <v>Type = rr_type()</v>
- <v>Opts = res_option() | verbose</v>
- <v>Timeout = integer() >= 0 | infinity</v>
- <v>Reason = posix() | res_error()</v>
- </type>
<desc>
<p>Resolve the DNS data for the record of the given type and class
for the given name. On success filters out the answer records
- with the correct <c>Class</c> and <c>Type</c> and returns
+ with the correct <c><anno>Class</anno></c> and <c><anno>Type</anno></c> and returns
a list of their data fields. So a lookup for type <c>any</c>
will give an empty answer since the answer records have
specific types that are not <c>any</c>. An empty answer
@@ -332,44 +255,33 @@ any of these data structures into a {Field,Value} list.</code>
</p><p>
Calls <seealso marker="#resolve/3">resolve/2..4</seealso>
with the same arguments and filters the result, so
- <c>Opts</c> is explained there.
+ <c><anno>Opts</anno></c> is explained there.
</p>
</desc>
</func>
<func>
- <name>resolve(Name, Class, Type) -> {ok,dns_msg()} | Error
- </name>
- <name>resolve(Name, Class, Type, Opts) -> {ok,dns_msg()} | Error
- </name>
- <name>resolve(Name, Class, Type, Opts, Timeout) -> {ok,dns_msg()} | Error
- </name>
+ <name name="resolve" arity="3"/>
+ <name name="resolve" arity="4"/>
+ <name name="resolve" arity="5"/>
<fsummary>Resolve a DNS record of the given type and class
for the given name
</fsummary>
- <type>
- <v>Name = dns_name() | ip_address()</v>
- <v>Type = rr_type()</v>
- <v>Opts = res_option() | verbose | atom()</v>
- <v>Timeout = integer() >= 0 | infinity</v>
- <v>Error = {error,Reason} | {error,{Reason,dns_msg()}}</v>
- <v>Reason = posix() | res_error()</v>
- </type>
<desc>
<p>Resolve a DNS record of the given type and class for the given name.
The returned <c>dns_msg()</c> can be examined using
access functions in <c>inet_db</c> as described
in <seealso marker="#dns_types">DNS types</seealso>.
</p><p>
- If <c>Name</c> is an <c>ip_address()</c>, the domain name
+ If <c><anno>Name</anno></c> is an <c>ip_address()</c>, the domain name
to query for is generated as the standard reverse
".IN-ADDR.ARPA." name for an IPv4 address, or the
".IP6.ARPA." name for an IPv6 address.
In this case you most probably want to use
- <c>Class = in</c> and <c>Type = ptr</c> but it
+ <c><anno>Class</anno> = in</c> and <c><anno>Type</anno> = ptr</c> but it
is not done automatically.
</p><p>
- <c>Opts</c> override the corresponding resolver options.
+ <c><anno>Opts</anno></c> override the corresponding resolver options.
If the option <c>nameservers</c> is given, it is
also assumed that it is the complete list of nameserves,
so the resolver option <c>alt_nameserves</c> is ignored.
@@ -382,14 +294,14 @@ any of these data structures into a {Field,Value} list.</code>
of queries, replies retransmissions, etc, similar
to from utilities like <c>dig</c>, <c>nslookup</c> et.al.
</p><p>
- If <c>Opt</c> is an arbitrary atom it is interpreted
- as <c>{Opt,true}</c> unless the atom string starts with
- <c>"no"</c> making the interpretation <c>{Opt,false}</c>.
+ If <c><anno>Opt</anno></c> is an arbitrary atom it is interpreted
+ as <c>{<anno>Opt</anno>,true}</c> unless the atom string starts with
+ <c>"no"</c> making the interpretation <c>{<anno>Opt</anno>,false}</c>.
For example: <c>usevc</c> is an alias for <c>{usevc,true}</c>,
and <c>nousevc</c> an alias for <c>{usevc,false}</c>.
</p><p>
The <c>inet6</c> option currently has no effect on this function.
- You probably want to use <c>Type = a | aaaa</c> instead.
+ You probably want to use <c><anno>Type</anno> = a | aaaa</c> instead.
</p>
</desc>
</func>
@@ -430,24 +342,18 @@ any of these data structures into a {Field,Value} list.</code>
<funcs>
<func>
- <name>nslookup(Name, Class, Type) -> {ok,dns_msg()} | {error,Reason}
- </name>
- <name>nslookup(Name, Class, Type, Timeout) ->
- {ok,dns_msg()} | {error,Reason}
- </name>
- <name>nslookup(Name, Class, Type, Nameservers) ->
- {ok,dns_msg()} | {error,Reason}
- </name>
+ <name name="nslookup" arity="3"/>
+ <name name="nslookup" arity="4" clause_i="1"/>
+ <name name="nslookup" arity="4" clause_i="2"/>
<fsummary>Resolve a DNS record of the given type and class
for the given name
</fsummary>
- <type>
- <v>Name = dns_name() | ip_address()</v>
- <v>Type = rr_type()</v>
- <v>Nameservers = [ nameserver() ]</v>
- <v>Timeout = integer() >= 0 | infinity</v>
- <v>Reason = posix() | res_error()</v>
- </type>
+ <type variable="Name"/>
+ <type variable="Class"/>
+ <type variable="Type"/>
+ <type variable="Timeout" name_i="2"/>
+ <type variable="Nameservers"/>
+ <type variable="Reason"/>
<desc>
<p>Resolve a DNS record of the given type and class for the given name.
</p>
@@ -455,22 +361,11 @@ any of these data structures into a {Field,Value} list.</code>
</func>
<func>
- <name>nnslookup(Name, Class, Type, Nameservers) ->
- {ok,dns_msg()} | {error,posix()}
- </name>
- <name>nnslookup(Name, Class, Type, Nameservers, Timeout) ->
- {ok,dns_msg()} | {error,posix()}
- </name>
+ <name name="nnslookup" arity="4"/>
+ <name name="nnslookup" arity="5"/>
<fsummary>Resolve a DNS record of the given type and class
for the given name
</fsummary>
- <type>
- <v>Name = dns_name() | ip_address()</v>
- <v>Type = rr_type()</v>
- <v>Nameservers = [ nameserver() ]</v>
- <v>Timeout = integer() >= 0 | infinity</v>
- <v>Reason = posix() | res_error()</v>
- </type>
<desc>
<p>Resolve a DNS record of the given type and class for the given name.
</p>
diff --git a/lib/kernel/doc/src/net_adm.xml b/lib/kernel/doc/src/net_adm.xml
index 7ec4f7f0e7..f2aac9282c 100644
--- a/lib/kernel/doc/src/net_adm.xml
+++ b/lib/kernel/doc/src/net_adm.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2009</year>
+ <year>1996</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -34,94 +34,70 @@
</description>
<funcs>
<func>
- <name>dns_hostname(Host) -> {ok, Name} | {error, Host}</name>
+ <name name="dns_hostname" arity="1"/>
<fsummary>Official name of a host</fsummary>
- <type>
- <v>Host = atom() | string()</v>
- <v>Name = string()</v>
- </type>
<desc>
- <p>Returns the official name of <c>Host</c>, or
- <c>{error, Host}</c> if no such name is found. See also
+ <p>Returns the official name of <c><anno>Host</anno></c>, or
+ <c>{error, <anno>Host</anno>}</c> if no such name is found. See also
<c>inet(3)</c>.</p>
</desc>
</func>
<func>
- <name>host_file() -> Hosts | {error, Reason}</name>
+ <name name="host_file" arity="0"/>
<fsummary>Read the <c>.hosts.erlang</c>file</fsummary>
- <type>
- <v>Hosts = [Host]</v>
- <v>&nbsp;Host = atom()</v>
- <v>Reason = term()</v>
- </type>
<desc>
<p>Reads the <c>.hosts.erlang</c> file, see the section
<em>Files</em> below. Returns the hosts in this file as a
- list, or returns <c>{error, Reason}</c> if the file could not
- be read. See <c>file(3)</c> for possible values of
- <c>Reason</c>.</p>
+ list, or returns <c>{error, <anno>Reason</anno>}</c> if the file could not
+ be read or the Erlang terms on the file could not be interpreted.</p>
</desc>
</func>
<func>
- <name>localhost() -> Name</name>
+ <name name="localhost" arity="0"/>
<fsummary>Name of the local host</fsummary>
- <type>
- <v>Name = string()</v>
- </type>
<desc>
<p>Returns the name of the local host. If Erlang was started
- with the <c>-name</c> command line flag, <c>Name</c> is
+ with the <c>-name</c> command line flag, <c><anno>Name</anno></c> is
the fully qualified name.</p>
</desc>
</func>
<func>
- <name>names() -> {ok, [{Name, Port}]} | {error, Reason}</name>
- <name>names(Host) -> {ok, [{Name, Port}]} | {error, Reason}</name>
+ <name name="names" arity="0"/>
+ <name name="names" arity="1"/>
<fsummary>Names of Erlang nodes at a host</fsummary>
- <type>
- <v>Name = string()</v>
- <v>Port = int()</v>
- <v>Reason = address | term()</v>
- </type>
<desc>
<p>Similar to <c>epmd -names</c>, see <c>epmd(1)</c>.
- <c>Host</c> defaults to the local host. Returns the names and
+ <c><anno>Host</anno></c> defaults to the local host. Returns the names and
associated port numbers of the Erlang nodes that <c>epmd</c>
at the specified host has registered.</p>
<p>Returns <c>{error, address}</c> if <c>epmd</c> is not
- running. See <c>inet(3)</c> for other possible values of
- <c>Reason</c>.</p>
+ running.</p>
<pre>
(arne@dunn)1> <input>net_adm:names().</input>
{ok,[{"arne",40262}]}</pre>
</desc>
</func>
<func>
- <name>ping(Node) -> pong | pang</name>
+ <name name="ping" arity="1"/>
<fsummary>Set up a connection to a node</fsummary>
- <type>
- <v>Node = node()</v>
- </type>
<desc>
- <p>Tries to set up a connection to <c>Node</c>. Returns
+ <p>Tries to set up a connection to <c><anno>Node</anno></c>. Returns
<c>pang</c> if it fails, or <c>pong</c> if it is successful.</p>
</desc>
</func>
<func>
- <name>world() -> [node()]</name>
- <name>world(Arg) -> [node()]</name>
+ <name name="world" arity="0"/>
+ <name name="world" arity="1"/>
+ <type name="verbosity"/>
<fsummary>Lookup and connect to all nodes at all hosts in <c>.hosts.erlang</c></fsummary>
- <type>
- <v>Arg = silent | verbose</v>
- </type>
<desc>
<p>This function calls <c>names(Host)</c> for all hosts which
are specified in the Erlang host file <c>.hosts.erlang</c>,
collects the replies and then evaluates <c>ping(Node)</c> on
all those nodes. Returns the list of all nodes that were,
successfully pinged.</p>
- <p><c>Arg</c> defaults to <c>silent</c>.
- If <c>Arg == verbose</c>, the function writes information about which
+ <p><c><anno>Arg</anno></c> defaults to <c>silent</c>.
+ If <c><anno>Arg</anno> == verbose</c>, the function writes information about which
nodes it is pinging to stdout.</p>
<p>This function can be useful when a node is started, and
the names of the other nodes in the network are not initially
@@ -131,14 +107,10 @@
</desc>
</func>
<func>
- <name>world_list(Hosts) -> [node()]</name>
- <name>world_list(Hosts, Arg) -> [node()]</name>
+ <name name="world_list" arity="1"/>
+ <name name="world_list" arity="2"/>
+ <type name="verbosity"/>
<fsummary>Lookup and connect to all nodes at specified hosts</fsummary>
- <type>
- <v>Hosts = [Host]</v>
- <v>&nbsp;Host = atom()</v>
- <v>Arg = silent | verbose</v>
- </type>
<desc>
<p>As <c>world/0,1</c>, but the hosts are given as argument
instead of being read from <c>.hosts.erlang</c>.</p>
diff --git a/lib/kernel/doc/src/net_kernel.xml b/lib/kernel/doc/src/net_kernel.xml
index a18226e779..96e2aa665d 100644
--- a/lib/kernel/doc/src/net_kernel.xml
+++ b/lib/kernel/doc/src/net_kernel.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2009</year>
+ <year>1996</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -64,50 +64,38 @@ $ <input>erl -sname foobar</input></pre>
</description>
<funcs>
<func>
- <name>allow(Nodes) -> ok | error</name>
+ <name name="allow" arity="1"/>
<fsummary>Limit access to a specified set of nodes</fsummary>
- <type>
- <v>Nodes = [node()]</v>
- </type>
<desc>
<p>Limits access to the specified set of nodes. Any access
- attempts made from (or to) nodes not in <c>Nodes</c> will be
+ attempts made from (or to) nodes not in <c><anno>Nodes</anno></c> will be
rejected.</p>
- <p>Returns <c>error</c> if any element in <c>Nodes</c> is not
+ <p>Returns <c>error</c> if any element in <c><anno>Nodes</anno></c> is not
an atom.</p>
</desc>
</func>
<func>
- <name>connect_node(Node) -> true | false | ignored</name>
+ <name name="connect_node" arity="1"/>
<fsummary>Establish a connection to a node</fsummary>
- <type>
- <v>Node = node()</v>
- </type>
<desc>
- <p>Establishes a connection to <c>Node</c>. Returns <c>true</c>
+ <p>Establishes a connection to <c><anno>Node</anno></c>. Returns <c>true</c>
if successful, <c>false</c> if not, and <c>ignored</c> if
the local node is not alive.</p>
</desc>
</func>
<func>
- <name>monitor_nodes(Flag) -> ok | Error</name>
- <name>monitor_nodes(Flag, Options) -> ok | Error</name>
+ <name name="monitor_nodes" arity="1"/>
+ <name name="monitor_nodes" arity="2"/>
<fsummary>Subscribe to node status change messages</fsummary>
- <type>
- <v>Flag = true | false</v>
- <v>Options = [Option]</v>
- <v>&nbsp;Option -- see below</v>
- <v>Error = error | {error, term()}</v>
- </type>
<desc>
<p>The calling process subscribes or unsubscribes to node
status change messages. A <c>nodeup</c> message is delivered
to all subscribing process when a new node is connected, and
a <c>nodedown</c> message is delivered when a node is
disconnected.</p>
- <p>If <c>Flag</c> is <c>true</c>, a new subscription is started.
- If <c>Flag</c> is <c>false</c>, all previous subscriptions --
- started with the same <c>Options</c> -- are stopped. Two
+ <p>If <c><anno>Flag</anno></c> is <c>true</c>, a new subscription is started.
+ If <c><anno>Flag</anno></c> is <c>false</c>, all previous subscriptions --
+ started with the same <c><anno>Options</anno></c> -- are stopped. Two
option lists are considered the same if they contain the same
set of options.</p>
<p>As of <c>kernel</c> version 2.11.4, and <c>erts</c> version
@@ -139,23 +127,23 @@ $ <input>erl -sname foobar</input></pre>
<p>Note, that this is <em>not</em> guaranteed for <c>kernel</c>
versions before 2.13.</p>
<p>The format of the node status change messages depends on
- <c>Options</c>. If <c>Options</c> is [], which is the default,
+ <c><anno>Options</anno></c>. If <c><anno>Options</anno></c> is [], which is the default,
the format is:</p>
<code type="none">
{nodeup, Node} | {nodedown, Node}
Node = node()</code>
- <p>If <c>Options /= []</c>, the format is:</p>
+ <p>If <c><anno>Options</anno> /= []</c>, the format is:</p>
<code type="none">
{nodeup, Node, InfoList} | {nodedown, Node, InfoList}
Node = node()
InfoList = [{Tag, Val}]</code>
<p><c>InfoList</c> is a list of tuples. Its contents depends on
- <c>Options</c>, see below.</p>
+ <c><anno>Options</anno></c>, see below.</p>
<p>Also, when <c>OptionList == []</c> only visible nodes, that
is, nodes that appear in the result of
<seealso marker="erts:erlang#nodes/0">nodes/0</seealso>, are
monitored.</p>
- <p><c>Option</c> can be any of the following:</p>
+ <p><c><anno>Option</anno></c> can be any of the following:</p>
<taglist>
<tag><c>{node_type, NodeType}</c></tag>
<item>
@@ -209,61 +197,51 @@ $ <input>erl -sname foobar</input></pre>
</desc>
</func>
<func>
- <name>get_net_ticktime() -> Res</name>
+ <name name="get_net_ticktime" arity="0"/>
<fsummary>Get <c>net_ticktime</c></fsummary>
- <type>
- <v>Res = NetTicktime | {ongoing_change_to, NetTicktime}</v>
- <v>&nbsp;NetTicktime = int()</v>
- </type>
<desc>
<p>Gets <c>net_ticktime</c> (see
<seealso marker="kernel_app">kernel(6)</seealso>).</p>
- <p>Currently defined return values (<c>Res</c>):</p>
+ <p>Currently defined return values (<c><anno>Res</anno></c>):</p>
<taglist>
- <tag><c>NetTicktime</c></tag>
+ <tag><c><anno>NetTicktime</anno></c></tag>
<item>
- <p><c>net_ticktime</c> is <c>NetTicktime</c> seconds.</p>
+ <p><c>net_ticktime</c> is <c><anno>NetTicktime</anno></c> seconds.</p>
</item>
- <tag><c>{ongoing_change_to, NetTicktime}</c></tag>
+ <tag><c>{ongoing_change_to, <anno>NetTicktime</anno>}</c></tag>
<item>
<p><c>net_kernel</c> is currently changing
- <c>net_ticktime</c> to <c>NetTicktime</c> seconds.</p>
+ <c>net_ticktime</c> to <c><anno>NetTicktime</anno></c> seconds.</p>
</item>
</taglist>
</desc>
</func>
<func>
- <name>set_net_ticktime(NetTicktime) -> Res</name>
- <name>set_net_ticktime(NetTicktime, TransitionPeriod) -> Res</name>
+ <name name="set_net_ticktime" arity="1"/>
+ <name name="set_net_ticktime" arity="2"/>
<fsummary>Set <c>net_ticktime</c></fsummary>
- <type>
- <v>NetTicktime = int() > 0</v>
- <v>TransitionPeriod = int() >= 0</v>
- <v>Res = unchanged | change_initiated | {ongoing_change_to, NewNetTicktime}</v>
- <v>&nbsp;NewNetTicktime = int() > 0</v>
- </type>
<desc>
<p>Sets <c>net_ticktime</c> (see
<seealso marker="kernel_app">kernel(6)</seealso>) to
- <c>NetTicktime</c> seconds. <c>TransitionPeriod</c> defaults
+ <c><anno>NetTicktime</anno></c> seconds. <c><anno>TransitionPeriod</anno></c> defaults
to 60.</p>
<p>Some definitions:</p>
<p></p>
<taglist>
<tag>The minimum transition traffic interval (<c>MTTI</c>)</tag>
<item>
- <p><c>minimum(NetTicktime, PreviousNetTicktime)*1000 div 4</c> milliseconds.</p>
+ <p><c>minimum(<anno>NetTicktime</anno>, PreviousNetTicktime)*1000 div 4</c> milliseconds.</p>
</item>
<tag>The transition period</tag>
<item>
<p>The time of the least number of consecutive <c>MTTI</c>s
- to cover <c>TransitionPeriod</c> seconds following
+ to cover <c><anno>TransitionPeriod</anno></c> seconds following
the call to <c>set_net_ticktime/2</c> (i.e.
- ((<c>TransitionPeriod*1000 - 1) div MTTI + 1)*MTTI</c>
+ ((<c><anno>TransitionPeriod</anno>*1000 - 1) div MTTI + 1)*MTTI</c>
milliseconds).</p>
</item>
</taglist>
- <p>If <c><![CDATA[NetTicktime < PreviousNetTicktime]]></c>, the actual
+ <p>If <c><![CDATA[<anno>NetTicktime</anno> < PreviousNetTicktime]]></c>, the actual
<c>net_ticktime</c> change will be done at the end of
the transition period; otherwise, at the beginning. During
the transition period, <c>net_kernel</c> will ensure that
@@ -271,7 +249,7 @@ $ <input>erl -sname foobar</input></pre>
every <c>MTTI</c> millisecond.</p>
<note>
<p>The <c>net_ticktime</c> changes have to be initiated on all
- nodes in the network (with the same <c>NetTicktime</c>)
+ nodes in the network (with the same <c><anno>NetTicktime</anno></c>)
before the end of any transition period on any node;
otherwise, connections may erroneously be disconnected.</p>
</note>
@@ -280,18 +258,18 @@ $ <input>erl -sname foobar</input></pre>
<tag><c>unchanged</c></tag>
<item>
<p><c>net_ticktime</c> already had the value of
- <c>NetTicktime</c> and was left unchanged.</p>
+ <c><anno>NetTicktime</anno></c> and was left unchanged.</p>
</item>
<tag><c>change_initiated</c></tag>
<item>
<p><c>net_kernel</c> has initiated the change of
- <c>net_ticktime</c> to <c>NetTicktime</c> seconds.</p>
+ <c>net_ticktime</c> to <c><anno>NetTicktime</anno></c> seconds.</p>
</item>
- <tag><c>{ongoing_change_to, NewNetTicktime}</c></tag>
+ <tag><c>{ongoing_change_to, <anno>NewNetTicktime</anno>}</c></tag>
<item>
<p>The request was <em>ignored</em>; because,
<c>net_kernel</c> was busy changing <c>net_ticktime</c> to
- <c>NewTicktime</c> seconds.</p>
+ <c><anno>NewNetTicktime</anno></c> seconds.</p>
</item>
</taglist>
</desc>
@@ -315,7 +293,7 @@ $ <input>erl -sname foobar</input></pre>
</desc>
</func>
<func>
- <name>stop() -> ok | {error, not_allowed | not_found}</name>
+ <name name="stop" arity="0"/>
<fsummary>Turn a node into a non-distributed Erlang runtime system</fsummary>
<desc>
<p>Turns a distributed node into a non-distributed node. For
diff --git a/lib/kernel/doc/src/os.xml b/lib/kernel/doc/src/os.xml
index 2c9cc33eb7..56fc1834ec 100644
--- a/lib/kernel/doc/src/os.xml
+++ b/lib/kernel/doc/src/os.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1997</year><year>2009</year>
+ <year>1997</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -38,13 +38,10 @@
</description>
<funcs>
<func>
- <name>cmd(Command) -> string()</name>
+ <name name="cmd" arity="1"/>
<fsummary>Execute a command in a shell of the target OS</fsummary>
- <type>
- <v>Command = string() | atom()</v>
- </type>
<desc>
- <p>Executes <c>Command</c> in a command shell of the target OS,
+ <p>Executes <c><anno>Command</anno></c> in a command shell of the target OS,
captures the standard output of the command and returns this
result as a string. This function is a replacement of
the previous <c>unix:cmd/1</c>; on a Unix platform they are
@@ -60,23 +57,18 @@ DirOut = os:cmd("dir"), % on Win32 platform</code>
</desc>
</func>
<func>
- <name>find_executable(Name) -> Filename | false</name>
- <name>find_executable(Name, Path) -> Filename | false</name>
+ <name name="find_executable" arity="1"/>
+ <name name="find_executable" arity="2"/>
<fsummary>Absolute filename of a program</fsummary>
- <type>
- <v>Name = string()</v>
- <v>Path = string()</v>
- <v>Filename = string()</v>
- </type>
<desc>
<p>These two functions look up an executable program given its
name and a search path, in the same way as the underlying
operating system. <c>find_executable/1</c> uses the current
execution path (that is, the environment variable PATH on
Unix and Windows).</p>
- <p><c>Path</c>, if given, should conform to the syntax of
+ <p><c><anno>Path</anno></c>, if given, should conform to the syntax of
execution paths on the operating system. The absolute
- filename of the executable program <c>Name</c> is returned,
+ filename of the executable program <c><anno>Name</anno></c> is returned,
or <c>false</c> if the program was not found.</p>
</desc>
</func>
@@ -137,7 +129,7 @@ DirOut = os:cmd("dir"), % on Win32 platform</code>
<name>timestamp() -> {MegaSecs, Secs, MicroSecs}</name>
<fsummary>Returna a timestamp from the OS in the erlang:now/0 format</fsummary>
<type>
- <v>MegaSecs = Secs = MicroSecs = int()</v>
+ <v>MegaSecs = Secs = MicroSecs = integer() >= 0</v>
</type>
<desc>
<p>Returns a tuple in the same format as <seealso marker="erts:erlang#now/0">erlang:now/0</seealso>. The difference is that this function returns what the operating system thinks (a.k.a. the wall clock time) without any attempts at time correction. The result of two different calls to this function is <em>not</em> guaranteed to be different.</p>
@@ -165,19 +157,15 @@ format_utc_timestamp() ->
</desc>
</func>
<func>
- <name>type() -> {Osfamily, Osname} | Osfamily</name>
+ <name name="type" arity="0"/>
<fsummary>Return the OS family and, in some cases, OS name of the current operating system</fsummary>
- <type>
- <v>Osfamily = win32 | unix | vxworks</v>
- <v>Osname = atom()</v>
- </type>
<desc>
- <p>Returns the <c>Osfamily</c> and, in some cases, <c>Osname</c>
+ <p>Returns the <c><anno>Osfamily</anno></c> and, in some cases, <c><anno>Osname</anno></c>
of the current operating system.</p>
- <p>On Unix, <c>Osname</c> will have same value as
+ <p>On Unix, <c><anno>Osname</anno></c> will have same value as
<c>uname -s</c> returns, but in lower case. For example, on
Solaris 1 and 2, it will be <c>sunos</c>.</p>
- <p>In Windows, <c>Osname</c> will be either <c>nt</c> (on
+ <p>In Windows, <c><anno>Osname</anno></c> will be either <c>nt</c> (on
Windows NT), or <c>windows</c> (on Windows 95).</p>
<p>On VxWorks the OS family alone is returned, that is
<c>vxworks</c>.</p>
@@ -185,17 +173,13 @@ format_utc_timestamp() ->
<p>Think twice before using this function. Use the
<c>filename</c> module if you want to inspect or build
file names in a portable way.
- Avoid matching on the <c>Osname</c> atom.</p>
+ Avoid matching on the <c><anno>Osname</anno></c> atom.</p>
</note>
</desc>
</func>
<func>
- <name>version() -> {Major, Minor, Release} | VersionString</name>
+ <name name="version" arity="0"/>
<fsummary>Return the Operating System version</fsummary>
- <type>
- <v>Major = Minor = Release = integer()</v>
- <v>VersionString = string()</v>
- </type>
<desc>
<p>Returns the operating system version.
On most systems, this function returns a tuple, but a string
diff --git a/lib/kernel/doc/src/pg2.xml b/lib/kernel/doc/src/pg2.xml
index 7463fd10f5..d26ff0fc6b 100644
--- a/lib/kernel/doc/src/pg2.xml
+++ b/lib/kernel/doc/src/pg2.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1997</year><year>2009</year>
+ <year>1997</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -60,13 +60,16 @@
to avoid name clashes.</p>
</warning>
</description>
+ <datatypes>
+ <datatype>
+ <name name="name"/>
+ <desc><p>The name of a process group.</p></desc>
+ </datatype>
+ </datatypes>
<funcs>
<func>
- <name>create(Name) -> void()</name>
+ <name name="create" arity="1"/>
<fsummary>Create a new, empty process group</fsummary>
- <type>
- <v>Name = term()</v>
- </type>
<desc>
<p>Creates a new, empty process group. The group is globally
visible on all nodes. If the group exists, nothing happens.
@@ -74,24 +77,16 @@
</desc>
</func>
<func>
- <name>delete(Name) -> void()</name>
+ <name name="delete" arity="1"/>
<fsummary>Delete a process group</fsummary>
- <type>
- <v>Name = term()</v>
- </type>
<desc>
<p>Deletes a process group.
</p>
</desc>
</func>
<func>
- <name>get_closest_pid(Name) -> Pid | {error, Reason}</name>
+ <name name="get_closest_pid" arity="1"/>
<fsummary>Common dispatch function</fsummary>
- <type>
- <v>Name = term()</v>
- <v>Pid = pid()</v>
- <v>Reason = {no_process, Name} | {no_such_group, Name}</v>
- </type>
<desc>
<p>This is a useful dispatch function which can be used from
client functions. It returns a process on the local node, if
@@ -100,13 +95,8 @@
</desc>
</func>
<func>
- <name>get_members(Name) -> [Pid] | {error, Reason}</name>
+ <name name="get_members" arity="1"/>
<fsummary>Return all processes in a group</fsummary>
- <type>
- <v>Name = term()</v>
- <v>Pid = pid()</v>
- <v>Reason = {no_such_group, Name}</v>
- </type>
<desc>
<p>Returns all processes in the group <c>Name</c>. This
function should be used from within a client function that
@@ -115,13 +105,8 @@
</desc>
</func>
<func>
- <name>get_local_members(Name) -> [Pid] | {error, Reason}</name>
+ <name name="get_local_members" arity="1"/>
<fsummary>Return all local processes in a group</fsummary>
- <type>
- <v>Name = term()</v>
- <v>Pid = pid()</v>
- <v>Reason = {no_such_group, Name}</v>
- </type>
<desc>
<p>Returns all processes running on the local node in the
group <c>Name</c>. This function should to be used from
@@ -131,13 +116,8 @@
</desc>
</func>
<func>
- <name>join(Name, Pid) -> ok | {error, Reason}</name>
+ <name name="join" arity="2"/>
<fsummary>Join a process to a group</fsummary>
- <type>
- <v>Name = term()</v>
- <v>Pid = pid()</v>
- <v>Reason = {no_such_group, Name}</v>
- </type>
<desc>
<p>Joins the process <c>Pid</c> to the group <c>Name</c>.
A process can join a group several times; it must then
@@ -146,13 +126,8 @@
</desc>
</func>
<func>
- <name>leave(Name, Pid) -> ok | {error, Reason}</name>
+ <name name="leave" arity="2"/>
<fsummary>Make a process leave a group</fsummary>
- <type>
- <v>Name = term()</v>
- <v>Pid = pid()</v>
- <v>Reason = {no_such_group, Name}</v>
- </type>
<desc>
<p>Makes the process <c>Pid</c> leave the group <c>Name</c>.
If the process is not a member of the group, <c>ok</c> is
@@ -161,24 +136,17 @@
</desc>
</func>
<func>
- <name>which_groups() -> [Name]</name>
+ <name name="which_groups" arity="0"/>
<fsummary>Return a list of all known groups</fsummary>
- <type>
- <v>Name = term()</v>
- </type>
<desc>
<p>Returns a list of all known groups.
</p>
</desc>
</func>
<func>
- <name>start()</name>
- <name>start_link() -> {ok, Pid} | {error, Reason}</name>
+ <name name="start" arity="0"/>
+ <name name="start_link" arity="0"/>
<fsummary>Start the pg2 server</fsummary>
- <type>
- <v>Pid = pid()</v>
- <v>Reason = term()</v>
- </type>
<desc>
<p>Starts the pg2 server. Normally, the server does not need
to be started explicitly, as it is started dynamically if it
diff --git a/lib/kernel/doc/src/rpc.xml b/lib/kernel/doc/src/rpc.xml
index 2b81de170d..b01ff16c85 100644
--- a/lib/kernel/doc/src/rpc.xml
+++ b/lib/kernel/doc/src/rpc.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2009</year>
+ <year>1996</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -37,40 +37,34 @@
for collecting information on a remote node, or for running a
function with some specific side effects on the remote node.</p>
</description>
+ <datatypes>
+ <datatype>
+ <name name="key"/>
+ <desc>
+ <p>As returned by <seealso marker="#async_call/4">
+ <c>async_call/4</c>.</seealso></p>
+ </desc>
+ </datatype>
+ </datatypes>
<funcs>
<func>
- <name>call(Node, Module, Function, Args) -> Res | {badrpc, Reason}</name>
+ <name name="call" arity="4"/>
<fsummary>Evaluate a function call on a node</fsummary>
- <type>
- <v>Node = node()</v>
- <v>Module = Function = atom()</v>
- <v>Args = [term()]</v>
- <v>Res = term()</v>
- <v>Reason = term()</v>
- </type>
<desc>
- <p>Evaluates <c>apply(Module, Function, Args)</c> on the node
- <c>Node</c> and returns the corresponding value <c>Res</c>, or
- <c>{badrpc, Reason}</c> if the call fails.</p>
+ <p>Evaluates <c>apply(<anno>Module</anno>, <anno>Function</anno>, <anno>Args</anno>)</c> on the node
+ <c><anno>Node</anno></c> and returns the corresponding value <c><anno>Res</anno></c>, or
+ <c>{badrpc, <anno>Reason</anno>}</c> if the call fails.</p>
</desc>
</func>
<func>
- <name>call(Node, Module, Function, Args, Timeout) -> Res | {badrpc, Reason}</name>
+ <name name="call" arity="5"/>
<fsummary>Evaluate a function call on a node</fsummary>
- <type>
- <v>Node = node()</v>
- <v>Module = Function = atom()</v>
- <v>Args = [term()]</v>
- <v>Res = term()</v>
- <v>Reason = timeout | term()</v>
- <v>Timeout = int() | infinity</v>
- </type>
<desc>
- <p>Evaluates <c>apply(Module, Function, Args)</c> on the node
- <c>Node</c> and returns the corresponding value <c>Res</c>, or
- <c>{badrpc, Reason}</c> if the call fails. <c>Timeout</c> is
+ <p>Evaluates <c>apply(<anno>Module</anno>, <anno>Function</anno>, <anno>Args</anno>)</c> on the node
+ <c><anno>Node</anno></c> and returns the corresponding value <c><anno>Res</anno></c>, or
+ <c>{badrpc, <anno>Reason</anno>}</c> if the call fails. <c><anno>Timeout</anno></c> is
a timeout value in milliseconds. If the call times out,
- <c>Reason</c> is <c>timeout</c>.</p>
+ <c><anno>Reason</anno></c> is <c>timeout</c>.</p>
<p>If the reply arrives after the call times out, no message
will contaminate the caller's message queue, since this
function spawns off a middleman process to act as (a void)
@@ -80,17 +74,10 @@
</desc>
</func>
<func>
- <name>block_call(Node, Module, Function, Args) -> Res | {badrpc, Reason}</name>
+ <name name="block_call" arity="4"/>
<fsummary>Evaluate a function call on a node in the RPC server's context</fsummary>
- <type>
- <v>Node = node()</v>
- <v>Module = Function = atom()</v>
- <v>Args = [term()]</v>
- <v>Res = term()</v>
- <v>Reason = term()</v>
- </type>
<desc>
- <p>Like <c>call/4</c>, but the RPC server at <c>Node</c> does
+ <p>Like <c>call/4</c>, but the RPC server at <c><anno>Node</anno></c> does
not create a separate process to handle the call. Thus,
this function can be used if the intention of the call is to
block the RPC server from any other incoming requests until
@@ -101,50 +88,31 @@
</desc>
</func>
<func>
- <name>block_call(Node, Module, Function, Args, Timeout) -> Res | {badrpc, Reason}</name>
+ <name name="block_call" arity="5"/>
<fsummary>Evaluate a function call on a node in the RPC server's context</fsummary>
- <type>
- <v>Node = node()</v>
- <v>Module = Function = atom()</v>
- <v>Args = [term()]</v>
- <v>Timeout = int() | infinity</v>
- <v>Res = term()</v>
- <v>Reason = term()</v>
- </type>
<desc>
<p>Like <c>block_call/4</c>, but with a timeout value in
the same manner as <c>call/5</c>.</p>
</desc>
</func>
<func>
- <name>async_call(Node, Module, Function, Args) -> Key</name>
+ <name name="async_call" arity="4"/>
<fsummary>Evaluate a function call on a node, asynchronous version</fsummary>
- <type>
- <v>Node = node()</v>
- <v>Module = Function = atom()</v>
- <v>Args = [term()]</v>
- <v>Key -- see below</v>
- </type>
<desc>
<p>Implements <em>call streams with promises</em>, a type of
RPC which does not suspend the caller until the result is
finished. Instead, a key is returned which can be used at a
later stage to collect the value. The key can be viewed as a
promise to deliver the answer.</p>
- <p>In this case, the key <c>Key</c> is returned, which can be
+ <p>In this case, the key <c><anno>Key</anno></c> is returned, which can be
used in a subsequent call to <c>yield/1</c> or
<c>nb_yield/1,2</c> to retrieve the value of evaluating
- <c>apply(Module, Function, Args)</c> on the node <c>Node</c>.</p>
+ <c>apply(<anno>Module</anno>, <anno>Function</anno>, <anno>Args</anno>)</c> on the node <c><anno>Node</anno></c>.</p>
</desc>
</func>
<func>
- <name>yield(Key) -> Res | {badrpc, Reason}</name>
+ <name name="yield" arity="1"/>
<fsummary>Deliver the result of evaluating a function call on a node (blocking)</fsummary>
- <type>
- <v>Key -- see async_call/4</v>
- <v>Res = term()</v>
- <v>Reason = term()</v>
- </type>
<desc>
<p>Returns the promised answer from a previous
<c>async_call/4</c>. If the answer is available, it is
@@ -153,87 +121,46 @@
</desc>
</func>
<func>
- <name>nb_yield(Key) -> {value, Val} | timeout</name>
+ <name name="nb_yield" arity="1"/>
<fsummary>Deliver the result of evaluating a function call on a node (non-blocking)</fsummary>
- <type>
- <v>Key -- see async_call/4</v>
- <v>Val = Res | {badrpc, Reason}</v>
- <v>&nbsp;Res = term()</v>
- <v>&nbsp;Reason = term()</v>
- </type>
<desc>
- <p>Equivalent to <c>nb_yield(Key, 0)</c>.</p>
+ <p>Equivalent to <c>nb_yield(<anno>Key</anno>, 0)</c>.</p>
</desc>
</func>
<func>
- <name>nb_yield(Key, Timeout) -> {value, Val} | timeout</name>
+ <name name="nb_yield" arity="2"/>
<fsummary>Deliver the result of evaluating a function call on a node (non-blocking)</fsummary>
- <type>
- <v>Key -- see async_call/4</v>
- <v>Timeout = int() | infinity</v>
- <v>Val = Res | {badrpc, Reason}</v>
- <v>&nbsp;Res = term()</v>
- <v>&nbsp;Reason = term()</v>
- </type>
<desc>
<p>This is a non-blocking version of <c>yield/1</c>. It returns
- the tuple <c>{value, Val}</c> when the computation has
- finished, or <c>timeout</c> when <c>Timeout</c> milliseconds
+ the tuple <c>{value, <anno>Val</anno>}</c> when the computation has
+ finished, or <c>timeout</c> when <c><anno>Timeout</anno></c> milliseconds
has elapsed.</p>
</desc>
</func>
<func>
- <name>multicall(Module, Function, Args) -> {ResL, BadNodes}</name>
+ <name name="multicall" arity="3"/>
<fsummary>Evaluate a function call on a number of nodes</fsummary>
- <type>
- <v>Module = Function = atom()</v>
- <v>Args = [term()]</v>
- <v>ResL = [term()]</v>
- <v>BadNodes = [node()]</v>
- </type>
<desc>
- <p>Equivalent to <c>multicall([node()|nodes()], Module, Function, Args, infinity)</c>.</p>
+ <p>Equivalent to <c>multicall([node()|nodes()], <anno>Module</anno>, <anno>Function</anno>, <anno>Args</anno>, infinity)</c>.</p>
</desc>
</func>
<func>
- <name>multicall(Nodes, Module, Function, Args) -> {ResL, BadNodes}</name>
+ <name name="multicall" arity="4" clause_i="1"/>
<fsummary>Evaluate a function call on a number of nodes</fsummary>
- <type>
- <v>Nodes = [node()]</v>
- <v>Module = Function = atom()</v>
- <v>Args = [term()]</v>
- <v>ResL = [term()]</v>
- <v>BadNodes = [node()]</v>
- </type>
<desc>
- <p>Equivalent to <c>multicall(Nodes, Module, Function, Args, infinity)</c>.</p>
+ <p>Equivalent to <c>multicall(<anno>Nodes</anno>, <anno>Module</anno>, <anno>Function</anno>, <anno>Args</anno>, infinity)</c>.</p>
</desc>
</func>
<func>
- <name>multicall(Module, Function, Args, Timeout) -> {ResL, BadNodes}</name>
+ <name name="multicall" arity="4" clause_i="2"/>
<fsummary>Evaluate a function call on a number of nodes</fsummary>
- <type>
- <v>Module = Function = atom()</v>
- <v>Args = [term()]</v>
- <v>Timeout = int() | infinity</v>
- <v>ResL = [term()]</v>
- <v>BadNodes = [node()]</v>
- </type>
<desc>
- <p>Equivalent to <c>multicall([node()|nodes()], Module, Function, Args, Timeout)</c>.</p>
+ <p>Equivalent to <c>multicall([node()|nodes()], <anno>Module</anno>, <anno>Function</anno>, <anno>Args</anno>, <anno>Timeout</anno>)</c>.</p>
</desc>
</func>
<func>
- <name>multicall(Nodes, Module, Function, Args, Timeout) -> {ResL, BadNodes}</name>
+ <name name="multicall" arity="5"/>
<fsummary>Evaluate a function call on a number of nodes</fsummary>
- <type>
- <v>Nodes = [node()]</v>
- <v>Module = Function = atom()</v>
- <v>Args = [term()]</v>
- <v>Timeout = int() | infinity</v>
- <v>ResL = [term()]</v>
- <v>BadNodes = [node()]</v>
- </type>
<desc>
<p>In contrast to an RPC, a multicall is an RPC which is sent
concurrently from one client to multiple servers. This is
@@ -243,12 +170,12 @@
making a series of RPCs on all the nodes, but the multicall
is faster as all the requests are sent at the same time
and are collected one by one as they come back.</p>
- <p>The function evaluates <c>apply(Module, Function, Args)</c>
+ <p>The function evaluates <c>apply(<anno>Module</anno>, <anno>Function</anno>, <anno>Args</anno>)</c>
on the specified nodes and collects the answers. It returns
- <c>{ResL, Badnodes}</c>, where <c>Badnodes</c> is a list
+ <c>{<anno>ResL</anno>, <anno>BadNodes</anno>}</c>, where <c><anno>BadNodes</anno></c> is a list
of the nodes that terminated or timed out during computation,
- and <c>ResL</c> is a list of the return values.
- <c>Timeout</c> is a time (integer) in milliseconds, or
+ and <c><anno>ResL</anno></c> is a list of the return values.
+ <c><anno>Timeout</anno></c> is a time (integer) in milliseconds, or
<c>infinity</c>.</p>
<p>The following example is useful when new object code is to
be loaded on all nodes in the network, and also indicates
@@ -264,93 +191,60 @@
</desc>
</func>
<func>
- <name>cast(Node, Module, Function, Args) -> void()</name>
+ <name name="cast" arity="4"/>
<fsummary>Run a function on a node ignoring the result</fsummary>
- <type>
- <v>Node = node()</v>
- <v>Module = Function = atom()</v>
- <v>Args = [term()]</v>
- </type>
<desc>
- <p>Evaluates <c>apply(Module, Function, Args)</c> on the node
- <c>Node</c>. No response is delivered and the calling
+ <p>Evaluates <c>apply(<anno>Module</anno>, <anno>Function</anno>, <anno>Args</anno>)</c> on the node
+ <c><anno>Node</anno></c>. No response is delivered and the calling
process is not suspended until the evaluation is complete, as
is the case with <c>call/4,5</c>.</p>
</desc>
</func>
<func>
- <name>eval_everywhere(Module, Funtion, Args) -> void()</name>
+ <name name="eval_everywhere" arity="3"/>
<fsummary>Run a function on all nodes, ignoring the result</fsummary>
- <type>
- <v>Module = Function = atom()</v>
- <v>Args = [term()]</v>
- </type>
<desc>
- <p>Equivalent to <c>eval_everywhere([node()|nodes()], Module, Function, Args)</c>.</p>
+ <p>Equivalent to <c>eval_everywhere([node()|nodes()], <anno>Module</anno>, <anno>Function</anno>, <anno>Args</anno>)</c>.</p>
</desc>
</func>
<func>
- <name>eval_everywhere(Nodes, Module, Function, Args) -> void()</name>
+ <name name="eval_everywhere" arity="4"/>
<fsummary>Run a function on specific nodes, ignoring the result</fsummary>
- <type>
- <v>Nodes = [node()]</v>
- <v>Module = Function = atom()</v>
- <v>Args = [term()]</v>
- </type>
<desc>
- <p>Evaluates <c>apply(Module, Function, Args)</c> on
+ <p>Evaluates <c>apply(<anno>Module</anno>, <anno>Function</anno>, <anno>Args</anno>)</c> on
the specified nodes. No answers are collected.</p>
</desc>
</func>
<func>
- <name>abcast(Name, Msg) -> void()</name>
+ <name name="abcast" arity="2"/>
<fsummary>Broadcast a message asynchronously to a registered process on all nodes</fsummary>
- <type>
- <v>Name = atom()</v>
- <v>Msg = term()</v>
- </type>
<desc>
- <p>Equivalent to <c>abcast([node()|nodes()], Name, Msg)</c>.</p>
+ <p>Equivalent to <c>abcast([node()|nodes()], <anno>Name</anno>, <anno>Msg</anno>)</c>.</p>
</desc>
</func>
<func>
- <name>abcast(Nodes, Name, Msg) -> void()</name>
+ <name name="abcast" arity="3"/>
<fsummary>Broadcast a message asynchronously to a registered process on specific nodes</fsummary>
- <type>
- <v>Nodes = [node()]</v>
- <v>Name = atom()</v>
- <v>Msg = term()</v>
- </type>
<desc>
- <p>Broadcasts the message <c>Msg</c> asynchronously to
- the registered process <c>Name</c> on the specified nodes.</p>
+ <p>Broadcasts the message <c><anno>Msg</anno></c> asynchronously to
+ the registered process <c><anno>Name</anno></c> on the specified nodes.</p>
</desc>
</func>
<func>
- <name>sbcast(Name, Msg) -> {GoodNodes, BadNodes}</name>
+ <name name="sbcast" arity="2"/>
<fsummary>Broadcast a message synchronously to a registered process on all nodes</fsummary>
- <type>
- <v>Name = atom()</v>
- <v>Msg = term()</v>
- <v>GoodNodes = BadNodes = [node()]</v>
- </type>
<desc>
- <p>Equivalent to <c>sbcast([node()|nodes()], Name, Msg)</c>.</p>
+ <p>Equivalent to <c>sbcast([node()|nodes()], <anno>Name</anno>, <anno>Msg</anno>)</c>.</p>
</desc>
</func>
<func>
- <name>sbcast(Nodes, Name, Msg) -> {GoodNodes, BadNodes}</name>
+ <name name="sbcast" arity="3"/>
<fsummary>Broadcast a message synchronously to a registered process on specific nodes</fsummary>
- <type>
- <v>Name = atom()</v>
- <v>Msg = term()</v>
- <v>Nodes = GoodNodes = BadNodes = [node()]</v>
- </type>
<desc>
- <p>Broadcasts the message <c>Msg</c> synchronously to
- the registered process <c>Name</c> on the specified nodes.</p>
- <p>Returns <c>{GoodNodes, BadNodes}</c>, where <c>GoodNodes</c>
- is the list of nodes which have <c>Name</c> as a registered
+ <p>Broadcasts the message <c><anno>Msg</anno></c> synchronously to
+ the registered process <c><anno>Name</anno></c> on the specified nodes.</p>
+ <p>Returns <c>{<anno>GoodNodes</anno>, <anno>BadNodes</anno>}</c>, where <c><anno>GoodNodes</anno></c>
+ is the list of nodes which have <c><anno>Name</anno></c> as a registered
process.</p>
<p>The function is synchronous in the sense that it is known
that all servers have received the message when the call
@@ -362,67 +256,46 @@
</desc>
</func>
<func>
- <name>server_call(Node, Name, ReplyWrapper, Msg) -> Reply | {error, Reason}</name>
+ <name name="server_call" arity="4"/>
<fsummary>Interact with a server on a node</fsummary>
- <type>
- <v>Node = node()</v>
- <v>Name = atom()</v>
- <v>ReplyWrapper = Msg = Reply = term()</v>
- <v>Reason = term()</v>
- </type>
<desc>
<p>This function can be used when interacting with a server
- called <c>Name</c> at node <c>Node</c>. It is assumed that
+ called <c><anno>Name</anno></c> at node <c><anno>Node</anno></c>. It is assumed that
the server receives messages in the format
- <c>{From, Msg}</c> and replies using <c>From ! {ReplyWrapper, Node, Reply}</c>. This function makes such
+ <c>{From, <anno>Msg</anno>}</c> and replies using <c>From ! {<anno>ReplyWrapper</anno>, <anno>Node</anno>, <anno>Reply</anno>}</c>. This function makes such
a server call and ensures that the entire call is packed into
an atomic transaction which either succeeds or fails. It
never hangs, unless the server itself hangs.</p>
- <p>The function returns the answer <c>Reply</c> as produced by
- the server <c>Name</c>, or <c>{error, Reason}</c>.</p>
+ <p>The function returns the answer <c><anno>Reply</anno></c> as produced by
+ the server <c><anno>Name</anno></c>, or <c>{error, <anno>Reason</anno>}</c>.</p>
</desc>
</func>
<func>
- <name>multi_server_call(Name, Msg) -> {Replies, BadNodes}</name>
+ <name name="multi_server_call" arity="2"/>
<fsummary>Interact with the servers on a number of nodes</fsummary>
- <type>
- <v>Name = atom()</v>
- <v>Msg = term()</v>
- <v>Replies = [Reply]</v>
- <v>&nbsp;Reply = term()</v>
- <v>BadNodes = [node()]</v>
- </type>
<desc>
- <p>Equivalent to <c>multi_server_call([node()|nodes()], Name, Msg)</c>.</p>
+ <p>Equivalent to <c>multi_server_call([node()|nodes()], <anno>Name</anno>, <anno>Msg</anno>)</c>.</p>
</desc>
</func>
<func>
- <name>multi_server_call(Nodes, Name, Msg) -> {Replies, BadNodes}</name>
+ <name name="multi_server_call" arity="3"/>
<fsummary>Interact with the servers on a number of nodes</fsummary>
- <type>
- <v>Nodes = [node()]</v>
- <v>Name = atom()</v>
- <v>Msg = term()</v>
- <v>Replies = [Reply]</v>
- <v>&nbsp;Reply = term()</v>
- <v>BadNodes = [node()]</v>
- </type>
<desc>
<p>This function can be used when interacting with servers
- called <c>Name</c> on the specified nodes. It is assumed that
- the servers receive messages in the format <c>{From, Msg}</c>
- and reply using <c>From ! {Name, Node, Reply}</c>, where
+ called <c><anno>Name</anno></c> on the specified nodes. It is assumed that
+ the servers receive messages in the format <c>{From, <anno>Msg</anno>}</c>
+ and reply using <c>From ! {<anno>Name</anno>, Node, <anno>Reply</anno>}</c>, where
<c>Node</c> is the name of the node where the server is
- located. The function returns <c>{Replies, Badnodes}</c>,
- where <c>Replies</c> is a list of all <c>Reply</c> values and
- <c>BadNodes</c> is a list of the nodes which did not exist, or
+ located. The function returns <c>{<anno>Replies</anno>, <anno>BadNodes</anno>}</c>,
+ where <c><anno>Replies</anno></c> is a list of all <c><anno>Reply</anno></c> values and
+ <c><anno>BadNodes</anno></c> is a list of the nodes which did not exist, or
where the server did not exist, or where the server terminated
before sending any reply.</p>
</desc>
</func>
<func>
- <name>safe_multi_server_call(Name, Msg) -> {Replies, BadNodes}</name>
- <name>safe_multi_server_call(Nodes, Name, Msg) -> {Replies, BadNodes}</name>
+ <name name="safe_multi_server_call" arity="2"/>
+ <name name="safe_multi_server_call" arity="3"/>
<fsummary>Interact with the servers on a number of nodes (deprecated)</fsummary>
<desc>
<warning>
@@ -432,66 +305,47 @@
<p>In Erlang/OTP R6B and earlier releases,
<c>multi_server_call/2,3</c> could not handle the case
where the remote node exists, but there is no server called
- <c>Name</c>. Instead this function had to be used. In
+ <c><anno>Name</anno></c>. Instead this function had to be used. In
Erlang/OTP R7B and later releases, however, the functions are
equivalent, except for this function being slightly slower.</p>
</desc>
</func>
<func>
- <name>parallel_eval(FuncCalls) -> ResL</name>
+ <name name="parallel_eval" arity="1"/>
<fsummary>Evaluate several function calls on all nodes in parallel</fsummary>
- <type>
- <v>FuncCalls = [{Module, Function, Args}]</v>
- <v>&nbsp;Module = Function = atom()</v>
- <v>&nbsp;Args = [term()]</v>
- <v>ResL = [term()]</v>
- </type>
<desc>
- <p>For every tuple in <c>FuncCalls</c>, evaluates
- <c>apply(Module, Function, Args)</c> on some node in
+ <p>For every tuple in <c><anno>FuncCalls</anno></c>, evaluates
+ <c>apply(<anno>Module</anno>, <anno>Function</anno>, <anno>Args</anno>)</c> on some node in
the network. Returns the list of return values, in the same
- order as in <c>FuncCalls</c>.</p>
+ order as in <c><anno>FuncCalls</anno></c>.</p>
</desc>
</func>
<func>
- <name>pmap({Module, Function}, ExtraArgs, List1) -> List2</name>
+ <name name="pmap" arity="3"/>
<fsummary>Parallell evaluation of mapping a function over a list </fsummary>
- <type>
- <v>Module = Function = atom()</v>
- <v>ExtraArgs = [term()]</v>
- <v>List1 = [Elem]</v>
- <v>&nbsp;Elem = term()</v>
- <v>List2 = [term()]</v>
- </type>
<desc>
- <p>Evaluates <c>apply(Module, Function, [Elem|ExtraArgs])</c>,
- for every element <c>Elem</c> in <c>List1</c>, in parallel.
+ <p>Evaluates <c>apply(<anno>Module</anno>, <anno>Function</anno>, [<anno>Elem</anno>|<anno>ExtraArgs</anno>])</c>,
+ for every element <c><anno>Elem</anno></c> in <c><anno>List1</anno></c>, in parallel.
Returns the list of return values, in the same order as in
- <c>List1</c>.</p>
+ <c><anno>List1</anno></c>.</p>
</desc>
</func>
<func>
- <name>pinfo(Pid) -> [{Item, Info}] | undefined</name>
+ <name name="pinfo" arity="1"/>
<fsummary>Information about a process</fsummary>
- <type>
- <v>Pid = pid()</v>
- <v>Item, Info -- see erlang:process_info/1</v>
- </type>
<desc>
<p>Location transparent version of the BIF
- <c>process_info/1</c>.</p>
+ <seealso marker="erts:erlang#process_info/1">
+ <c>process_info/1</c></seealso>.</p>
</desc>
</func>
<func>
- <name>pinfo(Pid, Item) -> {Item, Info} | undefined | []</name>
+ <name name="pinfo" arity="2"/>
<fsummary>Information about a process</fsummary>
- <type>
- <v>Pid = pid()</v>
- <v>Item, Info -- see erlang:process_info/1</v>
- </type>
<desc>
<p>Location transparent version of the BIF
- <c>process_info/2</c>.</p>
+ <seealso marker="erts:erlang#process_info/2">
+ <c>process_info/2</c></seealso>.</p>
</desc>
</func>
</funcs>
diff --git a/lib/kernel/doc/src/seq_trace.xml b/lib/kernel/doc/src/seq_trace.xml
index 6c043dd767..1ab955bd8a 100644
--- a/lib/kernel/doc/src/seq_trace.xml
+++ b/lib/kernel/doc/src/seq_trace.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1998</year><year>2009</year>
+ <year>1998</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -47,17 +47,22 @@
from users.</p>
</note>
</description>
+ <datatypes>
+ <datatype>
+ <name name="token"/>
+ <desc>
+ <p>An opaque term (a tuple) representing a trace token.</p>
+ </desc>
+ </datatype>
+ </datatypes>
<funcs>
<func>
- <name>set_token(Token) -> PreviousToken</name>
+ <name name="set_token" arity="1"/>
<fsummary>Set the trace token</fsummary>
- <type>
- <v>Token = PreviousToken = term() | []</v>
- </type>
<desc>
- <p>Sets the trace token for the calling process to <c>Token</c>.
- If <c>Token == []</c> then tracing is disabled, otherwise
- <c>Token</c> should be an Erlang term returned from
+ <p>Sets the trace token for the calling process to <c><anno>Token</anno></c>.
+ If <c><anno>Token</anno> == []</c> then tracing is disabled, otherwise
+ <c><anno>Token</anno></c> should be an Erlang term returned from
<c>get_token/0</c> or <c>set_token/1</c>. <c>set_token/1</c>
can be used to temporarily exclude message passing from
the trace by setting the trace token to empty like this:</p>
@@ -72,18 +77,16 @@ seq_trace:set_token(OldToken), % activate the trace token again
</desc>
</func>
<func>
- <name>set_token(Component, Val) -> {Component, OldVal}</name>
+ <name name="set_token" arity="2"/>
<fsummary>Set a component of the trace token</fsummary>
- <type>
- <v>Component = label | serial | Flag</v>
- <v>&nbsp;Flag = send | 'receive' | print | timestamp </v>
- <v>Val = OldVal -- see below</v>
- </type>
+ <type name="component"/>
+ <type name="flag"/>
+ <type name="value"/>
<desc>
- <p>Sets the individual <c>Component</c> of the trace token to
- <c>Val</c>. Returns the previous value of the component.</p>
+ <p>Sets the individual <c><anno>Component</anno></c> of the trace token to
+ <c><anno>Val</anno></c>. Returns the previous value of the component.</p>
<taglist>
- <tag><c>set_token(label, Int)</c></tag>
+ <tag><c>set_token(label, <anno>Integer</anno>)</c></tag>
<item>
<p>The <c>label</c> component is an integer which
identifies all events belonging to the same sequential
@@ -93,31 +96,31 @@ seq_trace:set_token(OldToken), % activate the trace token again
</item>
<tag><c>set_token(serial, SerialValue)</c></tag>
<item>
- <p><c>SerialValue = {Previous, Current}</c>.
+ <p><c>SerialValue = {<anno>Previous</anno>, <anno>Current</anno>}</c>.
The <c>serial</c> component contains counters which
enables the traced messages to be sorted, should never be
set explicitly by the user as these counters are updated
automatically. Default is <c>{0, 0}</c>.</p>
</item>
- <tag><c>set_token(send, Bool)</c></tag>
+ <tag><c>set_token(send, <anno>Bool</anno>)</c></tag>
<item>
<p>A trace token flag (<c>true | false</c>) which
enables/disables tracing on message sending. Default is
<c>false</c>.</p>
</item>
- <tag><c>set_token('receive', Bool)</c></tag>
+ <tag><c>set_token('receive', <anno>Bool</anno>)</c></tag>
<item>
<p>A trace token flag (<c>true | false</c>) which
enables/disables tracing on message reception. Default is
<c>false</c>.</p>
</item>
- <tag><c>set_token(print, Bool)</c></tag>
+ <tag><c>set_token(print, <anno>Bool</anno>)</c></tag>
<item>
<p>A trace token flag (<c>true | false</c>) which
enables/disables tracing on explicit calls to
<c>seq_trace:print/1</c>. Default is <c>false</c>.</p>
</item>
- <tag><c>set_token(timestamp, Bool)</c></tag>
+ <tag><c>set_token(timestamp, <anno>Bool</anno>)</c></tag>
<item>
<p>A trace token flag (<c>true | false</c>) which
enables/disables a timestamp to be generated for each
@@ -127,11 +130,8 @@ seq_trace:set_token(OldToken), % activate the trace token again
</desc>
</func>
<func>
- <name>get_token() -> TraceToken</name>
+ <name name="get_token" arity="0"/>
<fsummary>Return the value of the trace token</fsummary>
- <type>
- <v>TraceToken = term() | []</v>
- </type>
<desc>
<p>Returns the value of the trace token for the calling process.
If <c>[]</c> is returned, it means that tracing is not active.
@@ -141,13 +141,11 @@ seq_trace:set_token(OldToken), % activate the trace token again
</desc>
</func>
<func>
- <name>get_token(Component) -> {Component, Val}</name>
+ <name name="get_token" arity="1"/>
<fsummary>Return the value of a trace token component</fsummary>
- <type>
- <v>Component = label | serial | Flag</v>
- <v>&nbsp;Flag = send | 'receive' | print | timestamp </v>
- <v>Val -- see set_token/2</v>
- </type>
+ <type name="component"/>
+ <type name="flag"/>
+ <type name="value"/>
<desc>
<p>Returns the value of the trace token component
<c>Component</c>. See
@@ -156,33 +154,26 @@ seq_trace:set_token(OldToken), % activate the trace token again
</desc>
</func>
<func>
- <name>print(TraceInfo) -> void()</name>
+ <name name="print" arity="1"/>
<fsummary>Put the Erlang term <c>TraceInfo</c>into the sequential trace output</fsummary>
- <type>
- <v>TraceInfo = term()</v>
- </type>
<desc>
- <p>Puts the Erlang term <c>TraceInfo</c> into the sequential
+ <p>Puts the Erlang term <c><anno>TraceInfo</anno></c> into the sequential
trace output if the calling process currently is executing
within a sequential trace and the <c>print</c> flag of
the trace token is set.</p>
</desc>
</func>
<func>
- <name>print(Label, TraceInfo) -> void()</name>
+ <name name="print" arity="2"/>
<fsummary>Put the Erlang term <c>TraceInfo</c>into the sequential trace output</fsummary>
- <type>
- <v>Label = int()</v>
- <v>TraceInfo = term()</v>
- </type>
<desc>
<p>Same as <c>print/1</c> with the additional condition that
- <c>TraceInfo</c> is output only if <c>Label</c> is equal to
+ <c><anno>TraceInfo</anno></c> is output only if <c>Label</c> is equal to
the label component of the trace token.</p>
</desc>
</func>
<func>
- <name>reset_trace() -> void()</name>
+ <name name="reset_trace" arity="0"/>
<fsummary>Stop all sequential tracing on the local node</fsummary>
<desc>
<p>Sets the trace token to empty for all processes on the
@@ -194,26 +185,22 @@ seq_trace:set_token(OldToken), % activate the trace token again
</desc>
</func>
<func>
- <name>set_system_tracer(Tracer) -> OldTracer</name>
+ <name name="set_system_tracer" arity="1"/>
<fsummary>Set the system tracer</fsummary>
- <type>
- <v>Tracer = OldTracer = pid() | port() | false</v>
- </type>
+ <type name="tracer"/>
<desc>
<p>Sets the system tracer. The system tracer can be either a
- process or port denoted by <c>Tracer</c>. Returns the previous
+ process or port denoted by <c><anno>Tracer</anno></c>. Returns the previous
value (which can be <c>false</c> if no system tracer is
active).</p>
- <p>Failure: <c>{badarg, Info}}</c> if <c>Pid</c> is not an
+ <p>Failure: <c>{badarg, Info}}</c> if <c><anno>Pid</anno></c> is not an
existing local pid.</p>
</desc>
</func>
<func>
- <name>get_system_tracer() -> Tracer</name>
+ <name name="get_system_tracer" arity="0"/>
<fsummary>Return the pid() or port() of the current system tracer.</fsummary>
- <type>
- <v>Tracer = pid() | port() | false</v>
- </type>
+ <type name="tracer"/>
<desc>
<p>Returns the pid or port identifier of the current system
tracer or <c>false</c> if no system tracer is activated.</p>
diff --git a/lib/kernel/doc/src/specs.xml b/lib/kernel/doc/src/specs.xml
new file mode 100644
index 0000000000..b41addaa0c
--- /dev/null
+++ b/lib/kernel/doc/src/specs.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="latin1" ?>
+<specs xmlns:xi="http://www.w3.org/2001/XInclude">
+ <xi:include href="../specs/specs_application.xml"/>
+ <xi:include href="../specs/specs_auth.xml"/>
+ <xi:include href="../specs/specs_code.xml"/>
+ <xi:include href="../specs/specs_disk_log.xml"/>
+ <xi:include href="../specs/specs_erl_boot_server.xml"/>
+ <xi:include href="../specs/specs_erl_ddll.xml"/>
+ <xi:include href="../specs/specs_erl_prim_loader_stub.xml"/>
+ <xi:include href="../specs/specs_erlang_stub.xml"/>
+ <xi:include href="../specs/specs_error_handler.xml"/>
+ <xi:include href="../specs/specs_error_logger.xml"/>
+ <xi:include href="../specs/specs_file.xml"/>
+ <xi:include href="../specs/specs_gen_tcp.xml"/>
+ <xi:include href="../specs/specs_gen_udp.xml"/>
+ <xi:include href="../specs/specs_gen_sctp.xml"/>
+ <xi:include href="../specs/specs_global.xml"/>
+ <xi:include href="../specs/specs_global_group.xml"/>
+ <xi:include href="../specs/specs_heart.xml"/>
+ <xi:include href="../specs/specs_inet.xml"/>
+ <xi:include href="../specs/specs_inet_res.xml"/>
+ <xi:include href="../specs/specs_init_stub.xml"/>
+ <xi:include href="../specs/specs_net_adm.xml"/>
+ <xi:include href="../specs/specs_net_kernel.xml"/>
+ <xi:include href="../specs/specs_os.xml"/>
+ <xi:include href="../specs/specs_pg2.xml"/>
+ <xi:include href="../specs/specs_rpc.xml"/>
+ <xi:include href="../specs/specs_seq_trace.xml"/>
+ <xi:include href="../specs/specs_user.xml"/>
+ <xi:include href="../specs/specs_wrap_log_reader.xml"/>
+ <xi:include href="../specs/specs_zlib_stub.xml"/>
+ <xi:include href="../specs/specs_packages.xml"/>
+</specs>
diff --git a/lib/kernel/doc/src/wrap_log_reader.xml b/lib/kernel/doc/src/wrap_log_reader.xml
index 18664a029f..6cf480b532 100644
--- a/lib/kernel/doc/src/wrap_log_reader.xml
+++ b/lib/kernel/doc/src/wrap_log_reader.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1998</year><year>2009</year>
+ <year>1998</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -50,18 +50,20 @@
the called node, it is entirely up to the user to be sure that all items are read.
</p>
</description>
+ <datatypes>
+ <datatype>
+ <name name="continuation"/>
+ <desc><p>Continuation returned by
+ <c>open/1,2</c> or <c>chunk/1,2</c>.</p>
+ </desc>
+ </datatype>
+ </datatypes>
<funcs>
<func>
- <name>chunk(Continuation)</name>
- <name>chunk(Continuation, N) -> {Continuation2, Terms} | {Continuation2, Terms, Badbytes} | {Continuation2, eof} | {error, Reason}</name>
+ <name name="chunk" arity="1"/>
+ <name name="chunk" arity="2"/>
<fsummary>Read a chunk of objects written to a wrap log.</fsummary>
- <type>
- <v>Continuation = continuation()</v>
- <v>N = int() > 0 | infinity</v>
- <v>Continuation2 = continuation()</v>
- <v>Terms= [term()]</v>
- <v>Badbytes = integer()</v>
- </type>
+ <type name="chunk_ret"/>
<desc>
<p>This function makes it possible to efficiently read the
terms which have been appended to a log. It minimises disk
@@ -70,29 +72,29 @@
<p>The first time <c>chunk</c> is called an initial
continuation returned from the <c>open/1</c>, <c>open/2</c> must be provided.
</p>
- <p>When <c>chunk/3</c> is called, <c>N</c> controls the
+ <p>When <c>chunk/3</c> is called, <c><anno>N</anno></c> controls the
maximum number of terms that are read from the log in each
chunk. Default is <c>infinity</c>, which means that all the
terms contained in the 8K chunk are read. If less than
- <c>N</c> terms are returned, this does not necessarily mean
+ <c><anno>N</anno></c> terms are returned, this does not necessarily mean
that end of file is reached.
</p>
<p>The <c>chunk</c> function returns a tuple
- <c>{Continuation2, Terms}</c>, where <c>Terms</c> is a list
- of terms found in the log. <c>Continuation2</c> is yet
+ <c>{<anno>Continuation2</anno>, <anno>Terms</anno>}</c>, where <c><anno>Terms</anno></c> is a list
+ of terms found in the log. <c><anno>Continuation2</anno></c> is yet
another continuation which must be passed on into any
subsequent calls to <c>chunk</c>. With a series of calls to
<c>chunk</c> it is then possible to extract all terms from a
log.
</p>
<p>The <c>chunk</c> function returns a tuple
- <c>{Continuation2, Terms, Badbytes}</c> if the log is opened
- in read only mode and the read chunk is corrupt. <c>Badbytes</c>
+ <c>{<anno>Continuation2</anno>, <anno>Terms</anno>, <anno>Badbytes</anno>}</c> if the log is opened
+ in read only mode and the read chunk is corrupt. <c><anno>Badbytes</anno></c>
indicates the number of non-Erlang terms found in the chunk.
Note also that the log is not repaired.
</p>
- <p><c>chunk</c> returns <c>{Continuation2, eof}</c> when the end of the log is
- reached, and <c>{error, Reason}</c> if an error occurs.
+ <p><c>chunk</c> returns <c>{<anno>Continuation2</anno>, eof}</c> when the end of the log is
+ reached, and <c>{error, <anno>Reason</anno>}</c> if an error occurs.
</p>
<p>The returned continuation may or may not be valid in the next call to
<c>chunk</c>. This is because the log may wrap and delete
@@ -103,37 +105,29 @@
</desc>
</func>
<func>
- <name>close(Continuation) -> ok </name>
+ <name name="close" arity="1"/>
<fsummary>Close a log</fsummary>
- <type>
- <v>Continuation = continuation()</v>
- </type>
<desc>
<p>This function closes a log file properly.
</p>
</desc>
</func>
<func>
- <name>open(Filename) -> OpenRet</name>
- <name>open(Filename, N) -> OpenRet</name>
+ <name name="open" arity="1"/>
+ <name name="open" arity="2"/>
<fsummary>Open a log file</fsummary>
- <type>
- <v>File = string() | atom()</v>
- <v>N = integer()</v>
- <v>OpenRet = {ok, Continuation} | {error, Reason} </v>
- <v>Continuation = continuation()</v>
- </type>
+ <type name="open_ret"/>
<desc>
- <p><c>Filename</c> specifies the name of the file which is to be read. </p>
- <p><c>N</c> specifies the index of the file which is to be read.
- If <c>N</c> is omitted the whole wrap log file will be read; if it
+ <p><c><anno>Filename</anno></c> specifies the name of the file which is to be read. </p>
+ <p><c><anno>N</anno></c> specifies the index of the file which is to be read.
+ If <c><anno>N</anno></c> is omitted the whole wrap log file will be read; if it
is specified only the specified index file will be read.
</p>
- <p>The <c>open</c> function returns <c>{ok, Continuation}</c> if the
- log/index file was successfully opened. The <c>Continuation</c>
+ <p>The <c>open</c> function returns <c>{ok, <anno>Continuation</anno>}</c> if the
+ log/index file was successfully opened. The <c><anno>Continuation</anno></c>
is to be used when chunking or closing the file.
</p>
- <p>The function returns <c>{error, Reason}</c> for all errors.
+ <p>The function returns <c>{error, <anno>Reason</anno>}</c> for all errors.
</p>
</desc>
</func>
diff --git a/lib/kernel/include/inet.hrl b/lib/kernel/include/inet.hrl
index 929b2ee294..3e64d4bb79 100644
--- a/lib/kernel/include/inet.hrl
+++ b/lib/kernel/include/inet.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -19,18 +19,11 @@
%% This record is returned by inet:gethostbyaddr/2 and inet:gethostbyname/2.
--type hostname() :: atom() | string().
--type ip4_address() :: {0..255,0..255,0..255,0..255}.
--type ip6_address() :: {0..65535,0..65535,0..65535,0..65535,
- 0..65535,0..65535,0..65535,0..65535}.
--type ip_address() :: ip4_address() | ip6_address().
--type ip_port() :: 0..65535.
-
-record(hostent,
{
- h_name :: hostname(), %% offical name of host
- h_aliases = [] :: [hostname()], %% alias list
+ h_name :: inet:hostname(), %% offical name of host
+ h_aliases = [] :: [inet:hostname()], %% alias list
h_addrtype :: 'inet' | 'inet6', %% host address type
h_length :: non_neg_integer(), %% length of address
- h_addr_list = [] :: [ip_address()] %% list of addresses from name server
+ h_addr_list = [] :: [inet:ip_address()]%% list of addresses from name server
}).
diff --git a/lib/kernel/src/application.erl b/lib/kernel/src/application.erl
index 2a193affd4..fa3a4c3d36 100644
--- a/lib/kernel/src/application.erl
+++ b/lib/kernel/src/application.erl
@@ -32,20 +32,30 @@
%%%-----------------------------------------------------------------
+-type start_type() :: 'normal'
+ | {'takeover', Node :: node()}
+ | {'failover', Node :: node()}.
-type restart_type() :: 'permanent' | 'transient' | 'temporary'.
--type application_opt() :: {'description', string()}
- | {'vsn', string()}
- | {'id', string()}
- | {'modules', [atom() | {atom(), any()}]}
- | {'registered', [atom()]}
- | {'applications', [atom()]}
- | {'included_applications', [atom()]}
- | {'env', [{atom(), any()}]}
- | {'start_phases', [{atom(), any()}] | 'undefined'}
- | {'maxT', timeout()} % max timeout
- | {'maxP', integer() | 'infinity'} % max processes
- | {'mod', {atom(), any()}}.
--type application_spec() :: {'application', atom(), [application_opt()]}.
+-type application_opt() :: {'description', Description :: string()}
+ | {'vsn', Vsn :: string()}
+ | {'id', Id :: string()}
+ | {'modules', [(Module :: module()) |
+ {Module :: module(), Version :: term()}]}
+ | {'registered', Names :: [Name :: atom()]}
+ | {'applications', [Application :: atom()]}
+ | {'included_applications', [Application :: atom()]}
+ | {'env', [{Par :: atom(), Val :: term()}]}
+ | {'start_phases',
+ [{Phase :: atom(), PhaseArgs :: term()}] | 'undefined'}
+ | {'maxT', MaxT :: timeout()} % max timeout
+ | {'maxP',
+ MaxP :: pos_integer() | 'infinity'} % max processes
+ | {'mod', Start :: {Module :: module(), StartArgs :: term()}}.
+-type application_spec() :: {'application',
+ Application :: atom(),
+ AppSpecKeys :: [application_opt()]}.
+
+-type(tuple_of(_T) :: tuple()).
%%------------------------------------------------------------------
@@ -61,16 +71,29 @@ behaviour_info(_Other) ->
%%% application_master.
%%%-----------------------------------------------------------------
--spec load(Application :: atom() | application_spec()) ->
- 'ok' | {'error', term()}.
+-spec load(AppDescr) -> 'ok' | {'error', Reason} when
+ AppDescr :: Application | (AppSpec :: application_spec()),
+ Application :: atom(),
+ Reason :: term().
load(Application) ->
- load(Application, []).
-
--spec load(Application :: atom() | application_spec(),
- Distributed :: any()) -> 'ok' | {'error', term()}.
+ load1(Application, []).
+
+-spec load(AppDescr, Distributed) -> 'ok' | {'error', Reason} when
+ AppDescr :: Application | (AppSpec :: application_spec()),
+ Application :: atom(),
+ Distributed :: {Application,Nodes}
+ | {Application,Time,Nodes}
+ | 'default',
+ Nodes :: [node() | tuple_of(node())],
+ Time :: pos_integer(),
+ Reason :: term().
load(Application, DistNodes) ->
+ load1(Application, DistNodes).
+
+%% Workaround due to specs.
+load1(Application, DistNodes) ->
case application_controller:load_application(Application) of
ok when DistNodes =/= [] ->
AppName = get_appl_name(Application),
@@ -85,18 +108,24 @@ load(Application, DistNodes) ->
Else
end.
--spec unload(Application :: atom()) -> 'ok' | {'error', term()}.
+-spec unload(Application) -> 'ok' | {'error', Reason} when
+ Application :: atom(),
+ Reason :: term().
unload(Application) ->
application_controller:unload_application(Application).
--spec start(Application :: atom()) -> 'ok' | {'error', term()}.
+-spec start(Application) -> 'ok' | {'error', Reason} when
+ Application :: atom(),
+ Reason :: term().
start(Application) ->
start(Application, temporary).
--spec start(Application :: atom() | application_spec(),
- RestartType :: restart_type()) -> any().
+-spec start(Application, Type) -> 'ok' | {'error', Reason} when
+ Application :: atom(),
+ Type :: restart_type(),
+ Reason :: term().
start(Application, RestartType) ->
case load(Application) of
@@ -120,12 +149,18 @@ start_boot(Application) ->
start_boot(Application, RestartType) ->
application_controller:start_boot_application(Application, RestartType).
--spec takeover(Application :: atom(), RestartType :: restart_type()) -> any().
+-spec takeover(Application, Type) -> 'ok' | {'error', Reason} when
+ Application :: atom(),
+ Type :: restart_type(),
+ Reason :: term().
takeover(Application, RestartType) ->
dist_ac:takeover_application(Application, RestartType).
--spec permit(Application :: atom(), Bool :: boolean()) -> 'ok' | {'error', term()}.
+-spec permit(Application, Permission) -> 'ok' | {'error', Reason} when
+ Application :: atom(),
+ Permission :: boolean(),
+ Reason :: term().
permit(Application, Bool) ->
case Bool of
@@ -142,105 +177,146 @@ permit(Application, Bool) ->
LocalResult
end.
--spec stop(Application :: atom()) -> 'ok' | {'error', term()}.
+-spec stop(Application) -> 'ok' | {'error', Reason} when
+ Application :: atom(),
+ Reason :: term().
stop(Application) ->
application_controller:stop_application(Application).
--spec which_applications() -> [{atom(), string(), string()}].
+-spec which_applications() -> [{Application, Description, Vsn}] when
+ Application :: atom(),
+ Description :: string(),
+ Vsn :: string().
which_applications() ->
application_controller:which_applications().
--spec which_applications(timeout()) -> [{atom(), string(), string()}].
+-spec which_applications(Timeout) -> [{Application, Description, Vsn}] when
+ Timeout :: timeout(),
+ Application :: atom(),
+ Description :: string(),
+ Vsn :: string().
which_applications(infinity) ->
application_controller:which_applications(infinity);
which_applications(Timeout) when is_integer(Timeout), Timeout>=0 ->
application_controller:which_applications(Timeout).
--spec loaded_applications() -> [{atom(), string(), string()}].
+-spec loaded_applications() -> [{Application, Description, Vsn}] when
+ Application :: atom(),
+ Description :: string(),
+ Vsn :: string().
loaded_applications() ->
application_controller:loaded_applications().
--spec info() -> any().
+-spec info() -> term().
info() ->
application_controller:info().
--spec set_env(Application :: atom(), Key :: atom(), Value :: any()) -> 'ok'.
+-spec set_env(Application, Par, Val) -> 'ok' when
+ Application :: atom(),
+ Par :: atom(),
+ Val :: term().
set_env(Application, Key, Val) ->
application_controller:set_env(Application, Key, Val).
--spec set_env(Application :: atom(), Key :: atom(),
- Value :: any(), Timeout :: timeout()) -> 'ok'.
+-spec set_env(Application, Par, Val, Timeout) -> 'ok' when
+ Application :: atom(),
+ Par :: atom(),
+ Val :: term(),
+ Timeout :: timeout().
set_env(Application, Key, Val, infinity) ->
application_controller:set_env(Application, Key, Val, infinity);
set_env(Application, Key, Val, Timeout) when is_integer(Timeout), Timeout>=0 ->
application_controller:set_env(Application, Key, Val, Timeout).
--spec unset_env(atom(), atom()) -> 'ok'.
+-spec unset_env(Application, Par) -> 'ok' when
+ Application :: atom(),
+ Par :: atom().
unset_env(Application, Key) ->
application_controller:unset_env(Application, Key).
--spec unset_env(atom(), atom(), timeout()) -> 'ok'.
+-spec unset_env(Application, Par, Timeout) -> 'ok' when
+ Application :: atom(),
+ Par :: atom(),
+ Timeout :: timeout().
unset_env(Application, Key, infinity) ->
application_controller:unset_env(Application, Key, infinity);
unset_env(Application, Key, Timeout) when is_integer(Timeout), Timeout>=0 ->
application_controller:unset_env(Application, Key, Timeout).
--spec get_env(atom()) -> 'undefined' | {'ok', term()}.
+-spec get_env(Par) -> 'undefined' | {'ok', Val} when
+ Par :: atom(),
+ Val :: term().
get_env(Key) ->
application_controller:get_pid_env(group_leader(), Key).
--spec get_env(atom(), atom()) -> 'undefined' | {'ok', term()}.
+-spec get_env(Application, Par) -> 'undefined' | {'ok', Val} when
+ Application :: atom(),
+ Par :: atom(),
+ Val :: term().
get_env(Application, Key) ->
application_controller:get_env(Application, Key).
--spec get_all_env() -> [{atom(), any()}].
+-spec get_all_env() -> Env when
+ Env :: [{Par :: atom(), Val :: term()}].
get_all_env() ->
application_controller:get_pid_all_env(group_leader()).
--spec get_all_env(atom()) -> [{atom(), any()}].
+-spec get_all_env(Application) -> Env when
+ Application :: atom(),
+ Env :: [{Par :: atom(), Val :: term()}].
get_all_env(Application) ->
application_controller:get_all_env(Application).
--spec get_key(atom()) -> 'undefined' | {'ok', term()}.
+-spec get_key(Key) -> 'undefined' | {'ok', Val} when
+ Key :: atom(),
+ Val :: term().
get_key(Key) ->
application_controller:get_pid_key(group_leader(), Key).
--spec get_key(atom(), atom()) -> 'undefined' | {'ok', term()}.
+-spec get_key(Application, Key) -> 'undefined' | {'ok', Val} when
+ Application :: atom(),
+ Key :: atom(),
+ Val :: term().
get_key(Application, Key) ->
application_controller:get_key(Application, Key).
--spec get_all_key() -> 'undefined' | [] | {'ok', [{atom(),any()},...]}.
+-spec get_all_key() -> [] | {'ok', Keys} when
+ Keys :: [{Key :: atom(),Val :: term()},...].
get_all_key() ->
application_controller:get_pid_all_key(group_leader()).
--spec get_all_key(atom()) -> 'undefined' | {'ok', [{atom(),any()},...]}.
+-spec get_all_key(Application) -> 'undefined' | Keys when
+ Application :: atom(),
+ Keys :: {'ok', [{Key :: atom(),Val :: term()},...]}.
get_all_key(Application) ->
application_controller:get_all_key(Application).
--spec get_application() -> 'undefined' | {'ok', atom()}.
+-spec get_application() -> 'undefined' | {'ok', Application} when
+ Application :: atom().
get_application() ->
application_controller:get_application(group_leader()).
--spec get_application(Pid :: pid()) -> 'undefined' | {'ok', atom()}
- ; (Module :: atom()) -> 'undefined' | {'ok', atom()}.
+-spec get_application(PidOrModule) -> 'undefined' | {'ok', Application} when
+ PidOrModule :: (Pid :: pid()) | (Module :: module()),
+ Application :: atom().
get_application(Pid) when is_pid(Pid) ->
case process_info(Pid, group_leader) of
@@ -252,8 +328,8 @@ get_application(Pid) when is_pid(Pid) ->
get_application(Module) when is_atom(Module) ->
application_controller:get_application_module(Module).
--spec start_type() -> 'undefined' | 'local' | 'normal'
- | {'takeover', node()} | {'failover', node()}.
+-spec start_type() -> StartType | 'undefined' | 'local' when
+ StartType :: start_type().
start_type() ->
application_controller:start_type(group_leader()).
diff --git a/lib/kernel/src/auth.erl b/lib/kernel/src/auth.erl
index 5c7fe2421d..25c88a4e1d 100644
--- a/lib/kernel/src/auth.erl
+++ b/lib/kernel/src/auth.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -57,7 +57,8 @@ start_link() ->
%%--Deprecated interface------------------------------------------------
--spec is_auth(Node :: node()) -> 'yes' | 'no'.
+-spec is_auth(Node) -> 'yes' | 'no' when
+ Node :: Node :: node().
is_auth(Node) ->
case net_adm:ping(Node) of
@@ -65,12 +66,15 @@ is_auth(Node) ->
pang -> no
end.
--spec cookie() -> cookie().
+-spec cookie() -> Cookie when
+ Cookie :: cookie().
cookie() ->
get_cookie().
--spec cookie(Cookies :: [cookie(),...] | cookie()) -> 'true'.
+-spec cookie(TheCookie) -> 'true' when
+ TheCookie :: Cookie | [Cookie],
+ Cookie :: cookie().
cookie([Cookie]) ->
set_cookie(Cookie);
@@ -82,7 +86,9 @@ cookie(Cookie) ->
node_cookie([Node, Cookie]) ->
node_cookie(Node, Cookie).
--spec node_cookie(Node :: node(), Cookie :: cookie()) -> 'yes' | 'no'.
+-spec node_cookie(Node, Cookie) -> 'yes' | 'no' when
+ Node :: node(),
+ Cookie :: cookie().
node_cookie(Node, Cookie) ->
set_cookie(Node, Cookie),
diff --git a/lib/kernel/src/disk_log.erl b/lib/kernel/src/disk_log.erl
index 7f1b5f9ec6..9b8d2db437 100644
--- a/lib/kernel/src/disk_log.erl
+++ b/lib/kernel/src/disk_log.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -70,9 +70,10 @@
%%% Contract type specifications
%%%----------------------------------------------------------------------
+-opaque continuation() :: #continuation{}.
+
-type bytes() :: binary() | [byte()].
--type log() :: term(). % XXX: refine
-type file_error() :: term(). % XXX: refine
-type invalid_header() :: term(). % XXX: refine
@@ -87,27 +88,30 @@
-type open_error_rsn() :: 'no_such_log'
| {'badarg', term()}
- | {'size_mismatch', dlog_size(), dlog_size()}
- | {'arg_mismatch', dlog_optattr(), term(), term()}
- | {'name_already_open', log()}
- | {'open_read_write', log()}
- | {'open_read_only', log()}
- | {'need_repair', log()}
- | {'not_a_log_file', string()}
- | {'invalid_index_file', string()}
+ | {'size_mismatch', CurrentSize :: dlog_size(),
+ NewSize :: dlog_size()}
+ | {'arg_mismatch', OptionName :: dlog_optattr(),
+ CurrentValue :: term(), Value :: term()}
+ | {'name_already_open', Log :: log()}
+ | {'open_read_write', Log :: log()}
+ | {'open_read_only', Log :: log()}
+ | {'need_repair', Log :: log()}
+ | {'not_a_log_file', FileName :: file:filename()}
+ | {'invalid_index_file', FileName :: file:filename()}
| {'invalid_header', invalid_header()}
| {'file_error', file:filename(), file_error()}
- | {'node_already_open', log()}.
+ | {'node_already_open', Log :: log()}.
-type dist_error_rsn() :: 'nodedown' | open_error_rsn().
--type ret() :: {'ok', log()}
- | {'repaired', log(), {'recovered', non_neg_integer()},
- {'badbytes', non_neg_integer()}}.
+-type ret() :: {'ok', Log :: log()}
+ | {'repaired', Log :: log(),
+ {'recovered', Rec :: non_neg_integer()},
+ {'badbytes', Bad :: non_neg_integer()}}.
-type open_ret() :: ret() | {'error', open_error_rsn()}.
-type dist_open_ret() :: {[{node(), ret()}],
[{node(), {'error', dist_error_rsn()}}]}.
--type all_open_ret() :: open_ret() | dist_open_ret().
--spec open(Args :: dlog_options()) -> all_open_ret().
+-spec open(ArgL) -> open_ret() | dist_open_ret() when
+ ArgL :: dlog_options().
open(A) ->
disk_log_server:open(check_arg(A, #arg{options = A})).
@@ -116,40 +120,57 @@ open(A) ->
| {'full', log()} | {'invalid_header', invalid_header()}
| {'file_error', file:filename(), file_error()}.
--spec log(Log :: log(), Term :: term()) -> 'ok' | {'error', log_error_rsn()}.
+-spec log(Log, Term) -> ok | {error, Reason :: log_error_rsn()} when
+ Log :: log(),
+ Term :: term().
log(Log, Term) ->
req(Log, {log, term_to_binary(Term)}).
--spec blog(Log :: log(), Bytes :: bytes()) -> 'ok' | {'error', log_error_rsn()}.
+-spec blog(Log, Bytes) -> ok | {error, Reason :: log_error_rsn()} when
+ Log :: log(),
+ Bytes :: bytes().
blog(Log, Bytes) ->
req(Log, {blog, check_bytes(Bytes)}).
--spec log_terms(Log :: log(), Terms :: [term()]) -> 'ok' | {'error', term()}.
+-spec log_terms(Log, TermList) -> ok | {error, Resaon :: log_error_rsn()} when
+ Log :: log(),
+ TermList :: [term()].
log_terms(Log, Terms) ->
Bs = terms2bins(Terms),
req(Log, {log, Bs}).
--spec blog_terms(Log :: log(), Bytes :: [bytes()]) -> 'ok' | {'error', term()}.
+-spec blog_terms(Log, BytesList) ->
+ ok | {error, Reason :: log_error_rsn()} when
+ Log :: log(),
+ BytesList :: [bytes()].
blog_terms(Log, Bytess) ->
Bs = check_bytes_list(Bytess, Bytess),
req(Log, {blog, Bs}).
-type notify_ret() :: 'ok' | {'error', 'no_such_log'}.
--spec alog(Log :: log(), Term :: term()) -> notify_ret().
+-spec alog(Log, Term) -> notify_ret() when
+ Log :: log(),
+ Term :: term().
alog(Log, Term) ->
notify(Log, {alog, term_to_binary(Term)}).
--spec alog_terms(Log :: log(), Terms :: [term()]) -> notify_ret().
+-spec alog_terms(Log, TermList) -> notify_ret() when
+ Log :: log(),
+ TermList :: [term()].
alog_terms(Log, Terms) ->
Bs = terms2bins(Terms),
notify(Log, {alog, Bs}).
--spec balog(Log :: log(), Bytes :: bytes()) -> notify_ret().
+-spec balog(Log, Bytes) -> notify_ret() when
+ Log :: log(),
+ Bytes :: bytes().
balog(Log, Bytes) ->
notify(Log, {balog, check_bytes(Bytes)}).
--spec balog_terms(Log :: log(), Bytes :: [bytes()]) -> notify_ret().
+-spec balog_terms(Log, ByteList) -> notify_ret() when
+ Log :: log(),
+ ByteList :: [bytes()].
balog_terms(Log, Bytess) ->
Bs = check_bytes_list(Bytess, Bytess),
notify(Log, {balog, Bs}).
@@ -157,18 +178,22 @@ balog_terms(Log, Bytess) ->
-type close_error_rsn() ::'no_such_log' | 'nonode'
| {'file_error', file:filename(), file_error()}.
--spec close(Log :: log()) -> 'ok' | {'error', close_error_rsn()}.
+-spec close(Log) -> 'ok' | {'error', close_error_rsn()} when
+ Log :: log().
close(Log) ->
req(Log, close).
-type lclose_error_rsn() :: 'no_such_log'
| {'file_error', file:filename(), file_error()}.
--spec lclose(Log :: log()) -> 'ok' | {'error', lclose_error_rsn()}.
+-spec lclose(Log) -> 'ok' | {'error', lclose_error_rsn()} when
+ Log :: log().
lclose(Log) ->
lclose(Log, node()).
--spec lclose(Log :: log(), Node :: node()) -> 'ok' | {'error', lclose_error_rsn()}.
+-spec lclose(Log, Node) -> 'ok' | {'error', lclose_error_rsn()} when
+ Log :: log(),
+ Node :: node().
lclose(Log, Node) ->
lreq(Log, close, Node).
@@ -178,29 +203,49 @@ lclose(Log, Node) ->
| {'invalid_header', invalid_header()}
| {'file_error', file:filename(), file_error()}.
--spec truncate(Log :: log()) -> 'ok' | {'error', trunc_error_rsn()}.
+-spec truncate(Log) -> 'ok' | {'error', trunc_error_rsn()} when
+ Log :: log().
truncate(Log) ->
req(Log, {truncate, none, truncate, 1}).
--spec truncate(Log :: log(), Head :: term()) -> 'ok' | {'error', trunc_error_rsn()}.
+-spec truncate(Log, Head) -> 'ok' | {'error', trunc_error_rsn()} when
+ Log :: log(),
+ Head :: term().
truncate(Log, Head) ->
req(Log, {truncate, {ok, term_to_binary(Head)}, truncate, 2}).
--spec btruncate(Log :: log(), Head :: bytes()) -> 'ok' | {'error', trunc_error_rsn()}.
+-spec btruncate(Log, BHead) -> 'ok' | {'error', trunc_error_rsn()} when
+ Log :: log(),
+ BHead :: bytes().
btruncate(Log, Head) ->
req(Log, {truncate, {ok, check_bytes(Head)}, btruncate, 2}).
--spec reopen(Log :: log(), Filename :: file:filename()) -> 'ok' | {'error', term()}.
+-type reopen_error_rsn() :: no_such_log
+ | nonode
+ | {read_only_mode, log()}
+ | {blocked_log, log()}
+ | {same_file_name, log()} |
+ {invalid_index_file, file:filename()}
+ | {invalid_header, invalid_header()}
+ | {'file_error', file:filename(), file_error()}.
+
+-spec reopen(Log, File) -> 'ok' | {'error', reopen_error_rsn()} when
+ Log :: log(),
+ File :: file:filename().
reopen(Log, NewFile) ->
req(Log, {reopen, NewFile, none, reopen, 2}).
--spec reopen(Log :: log(), Filename :: file:filename(), Head :: term()) ->
- 'ok' | {'error', term()}.
+-spec reopen(Log, File, Head) -> 'ok' | {'error', reopen_error_rsn()} when
+ Log :: log(),
+ File :: file:filename(),
+ Head :: term().
reopen(Log, NewFile, NewHead) ->
req(Log, {reopen, NewFile, {ok, term_to_binary(NewHead)}, reopen, 3}).
--spec breopen(Log :: log(), Filename :: file:filename(), Head :: bytes()) ->
- 'ok' | {'error', term()}.
+-spec breopen(Log, File, BHead) -> 'ok' | {'error', reopen_error_rsn()} when
+ Log :: log(),
+ File :: file:filename(),
+ BHead :: bytes().
breopen(Log, NewFile, NewHead) ->
req(Log, {reopen, NewFile, {ok, check_bytes(NewHead)}, breopen, 3}).
@@ -210,21 +255,36 @@ breopen(Log, NewFile, NewHead) ->
| {'invalid_header', invalid_header()}
| {'file_error', file:filename(), file_error()}.
--spec inc_wrap_file(Log :: log()) -> 'ok' | {'error', inc_wrap_error_rsn()}.
+-spec inc_wrap_file(Log) -> 'ok' | {'error', inc_wrap_error_rsn()} when
+ Log :: log().
inc_wrap_file(Log) ->
req(Log, inc_wrap_file).
--spec change_size(Log :: log(), Size :: dlog_size()) -> 'ok' | {'error', term()}.
+-spec change_size(Log, Size) -> 'ok' | {'error', Reason} when
+ Log :: log(),
+ Size :: dlog_size(),
+ Reason :: no_such_log | nonode | {read_only_mode, Log}
+ | {blocked_log, Log}
+ | {new_size_too_small, CurrentSize :: pos_integer()}
+ | {badarg, size}
+ | {file_error, file:filename(), file_error()}.
change_size(Log, NewSize) ->
req(Log, {change_size, NewSize}).
--spec change_notify(Log :: log(), Pid :: pid(), Notify :: boolean()) ->
- 'ok' | {'error', term()}.
+-spec change_notify(Log, Owner, Notify) -> 'ok' | {'error', Reason} when
+ Log :: log(),
+ Owner :: pid(),
+ Notify :: boolean(),
+ Reason :: no_such_log | nonode | {blocked_log, Log}
+ | {badarg, notify} | {not_owner, Owner}.
change_notify(Log, Pid, NewNotify) ->
req(Log, {change_notify, Pid, NewNotify}).
--spec change_header(Log :: log(), Head :: {atom(), term()}) ->
- 'ok' | {'error', term()}.
+-spec change_header(Log, Header) -> 'ok' | {'error', Reason} when
+ Log :: log(),
+ Header :: {head, dlog_head_opt()} | {head_func, mfa()},
+ Reason :: no_such_log | nonode | {read_only_mode, Log}
+ | {blocked_log, Log} | {badarg, head}.
change_header(Log, NewHead) ->
req(Log, {change_header, NewHead}).
@@ -232,17 +292,21 @@ change_header(Log, NewHead) ->
| {'blocked_log', log()}
| {'file_error', file:filename(), file_error()}.
--spec sync(Log :: log()) -> 'ok' | {'error', sync_error_rsn()}.
+-spec sync(Log) -> 'ok' | {'error', sync_error_rsn()} when
+ Log :: log().
sync(Log) ->
req(Log, sync).
-type block_error_rsn() :: 'no_such_log' | 'nonode' | {'blocked_log', log()}.
--spec block(Log :: log()) -> 'ok' | {'error', block_error_rsn()}.
+-spec block(Log) -> 'ok' | {'error', block_error_rsn()} when
+ Log :: log().
block(Log) ->
block(Log, true).
--spec block(Log :: log(), QueueLogRecords :: boolean()) -> 'ok' | {'error', term()}.
+-spec block(Log, QueueLogRecords) -> 'ok' | {'error', block_error_rsn()} when
+ Log :: log(),
+ QueueLogRecords :: boolean().
block(Log, QueueLogRecords) ->
req(Log, {block, QueueLogRecords}).
@@ -250,19 +314,46 @@ block(Log, QueueLogRecords) ->
| {'not_blocked', log()}
| {'not_blocked_by_pid', log()}.
--spec unblock(Log :: log()) -> 'ok' | {'error', unblock_error_rsn()}.
+-spec unblock(Log) -> 'ok' | {'error', unblock_error_rsn()} when
+ Log :: log().
unblock(Log) ->
req(Log, unblock).
--spec format_error(Error :: term()) -> string().
+-spec format_error(Error) -> io_lib:chars() when
+ Error :: term().
format_error(Error) ->
do_format_error(Error).
--spec info(Log :: log()) -> [{atom(), any()}] | {'error', term()}.
+-type dlog_info() :: {name, Log :: log()}
+ | {file, File :: file:filename()}
+ | {type, Type :: dlog_type()}
+ | {format, Format :: dlog_format()}
+ | {size, Size :: dlog_size()}
+ | {mode, Mode :: dlog_mode()}
+ | {owners, [{pid(), Notify :: boolean()}]}
+ | {users, Users :: non_neg_integer()}
+ | {status, Status ::
+ ok | {blocked, QueueLogRecords :: boolean()}}
+ | {node, Node :: node()}
+ | {distributed, Dist :: local | [node()]}
+ | {head, Head :: none | {head, term()} | mfa()}
+ | {no_written_items, NoWrittenItems ::non_neg_integer()}
+ | {full, Full :: boolean}
+ | {no_current_bytes, non_neg_integer()}
+ | {no_current_items, non_neg_integer()}
+ | {no_items, non_neg_integer()}
+ | {current_file, pos_integer()}
+ | {no_overflows, {SinceLogWasOpened :: non_neg_integer(),
+ SinceLastInfo :: non_neg_integer()}}.
+-spec info(Log) -> InfoList | {'error', no_such_log} when
+ Log :: log(),
+ InfoList :: [dlog_info()].
info(Log) ->
sreq(Log, info).
--spec pid2name(Pid :: pid()) -> {'ok', log()} | 'undefined'.
+-spec pid2name(Pid) -> {'ok', Log} | 'undefined' when
+ Pid :: pid(),
+ Log :: log().
pid2name(Pid) ->
disk_log_server:start(),
case ets:lookup(?DISK_LOG_PID_TABLE, Pid) of
@@ -274,13 +365,31 @@ pid2name(Pid) ->
%% It retuns a {Cont2, ObjList} | eof | {error, Reason}
%% The initial continuation is the atom 'start'
--spec chunk(Log :: log(), Cont :: any()) ->
- {'error', term()} | 'eof' | {any(), [any()]} | {any(), [any()], integer()}.
+-type chunk_error_rsn() :: no_such_log
+ | {format_external, log()}
+ | {blocked_log, log()}
+ | {badarg, continuation}
+ | {not_internal_wrap, log()}
+ | {corrupt_log_file, FileName :: file:filename()}
+ | {file_error, file:filename(), file_error()}.
+
+-type chunk_ret() :: {Continuation2 :: continuation(), Terms :: [term()]}
+ | {Continuation2 :: continuation(),
+ Terms :: [term()],
+ Badbytes :: non_neg_integer()}
+ | eof
+ | {error, Reason :: chunk_error_rsn()}.
+
+-spec chunk(Log, Continuation) -> chunk_ret() when
+ Log :: log(),
+ Continuation :: start | continuation().
chunk(Log, Cont) ->
chunk(Log, Cont, infinity).
--spec chunk(Log :: log(), Cont :: any(), N :: pos_integer() | 'infinity') ->
- {'error', term()} | 'eof' | {any(), [any()]} | {any(), [any()], integer()}.
+-spec chunk(Log, Continuation, N) -> chunk_ret() when
+ Log :: log(),
+ Continuation :: start | continuation(),
+ N :: pos_integer() | infinity.
chunk(Log, Cont, infinity) ->
%% There cannot be more than ?MAX_CHUNK_SIZE terms in a chunk.
ichunk(Log, Cont, ?MAX_CHUNK_SIZE);
@@ -346,13 +455,24 @@ ichunk_bad_end([B | Bs], Mode, Log, C, Bad, A) ->
ichunk_bad_end(Bs, Mode, Log, C, Bad, [T | A])
end.
--spec bchunk(Log :: log(), Cont :: any()) ->
- {'error', any()} | 'eof' | {any(), [binary()]} | {any(), [binary()], integer()}.
+-type bchunk_ret() :: {Continuation2 :: continuation(),
+ Binaries :: [binary()]}
+ | {Continuation2 :: continuation(),
+ Binaries :: [binary()],
+ Badbytes :: non_neg_integer()}
+ | eof
+ | {error, Reason :: chunk_error_rsn()}.
+
+-spec bchunk(Log, Continuation) -> bchunk_ret() when
+ Log :: log(),
+ Continuation :: start | continuation().
bchunk(Log, Cont) ->
bchunk(Log, Cont, infinity).
--spec bchunk(Log :: log(), Cont :: any(), N :: 'infinity' | pos_integer()) ->
- {'error', any()} | 'eof' | {any(), [binary()]} | {any(), [binary()], integer()}.
+-spec bchunk(Log, Continuation, N) -> bchunk_ret() when
+ Log :: log(),
+ Continuation :: start | continuation(),
+ N :: pos_integer() | infinity.
bchunk(Log, Cont, infinity) ->
%% There cannot be more than ?MAX_CHUNK_SIZE terms in a chunk.
bichunk(Log, Cont, ?MAX_CHUNK_SIZE);
@@ -375,8 +495,14 @@ bichunk_end({C = #continuation{}, R, Bad}) ->
bichunk_end(R) ->
R.
--spec chunk_step(Log :: log(), Cont :: any(), N :: integer()) ->
- {'ok', any()} | {'error', term()}.
+-spec chunk_step(Log, Continuation, Step) ->
+ {'ok', any()} | {'error', Reason} when
+ Log :: log(),
+ Continuation :: start | continuation(),
+ Step :: integer(),
+ Reason :: no_such_log | end_of_log | {format_external, Log}
+ | {blocked_log, Log} | {badarg, continuation}
+ | {file_error, file:filename(), file_error()}.
chunk_step(Log, Cont, N) when is_integer(N) ->
ichunk_step(Log, Cont, N).
@@ -387,14 +513,18 @@ ichunk_step(_Log, More, N) when is_record(More, continuation) ->
ichunk_step(_Log, _, _) ->
{error, {badarg, continuation}}.
--spec chunk_info(More :: any()) ->
- [{'node', node()},...] | {'error', {'no_continuation', any()}}.
+-spec chunk_info(Continuation) -> InfoList | {error, Reason} when
+ Continuation :: continuation(),
+ InfoList :: [{node, Node :: node()}, ...],
+ Reason :: {no_continuation, Continuation}.
chunk_info(More = #continuation{}) ->
[{node, node(More#continuation.pid)}];
chunk_info(BadCont) ->
{error, {no_continuation, BadCont}}.
--spec accessible_logs() -> {[_], [_]}.
+-spec accessible_logs() -> {[LocalLog], [DistributedLog]} when
+ LocalLog :: log(),
+ DistributedLog :: log().
accessible_logs() ->
disk_log_server:accessible_logs().
diff --git a/lib/kernel/src/disk_log.hrl b/lib/kernel/src/disk_log.hrl
index 9a94d4d3b9..259967650f 100644
--- a/lib/kernel/src/disk_log.hrl
+++ b/lib/kernel/src/disk_log.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -53,18 +53,34 @@
%% Types -- alphabetically
%%------------------------------------------------------------------------
+-type dlog_byte() :: [dlog_byte()] | byte().
-type dlog_format() :: 'external' | 'internal'.
-type dlog_format_type() :: 'halt_ext' | 'halt_int' | 'wrap_ext' | 'wrap_int'.
-type dlog_head() :: 'none' | {'ok', binary()} | mfa().
+-type dlog_head_opt() :: none | term() | binary() | [dlog_byte()].
+-type log() :: term(). % XXX: refine
-type dlog_mode() :: 'read_only' | 'read_write'.
-type dlog_name() :: atom() | string().
-type dlog_optattr() :: 'name' | 'file' | 'linkto' | 'repair' | 'type'
| 'format' | 'size' | 'distributed' | 'notify'
| 'head' | 'head_func' | 'mode'.
--type dlog_options() :: [{dlog_optattr(), any()}].
+-type dlog_option() :: {name, Log :: log()}
+ | {file, FileName :: file:filename()}
+ | {linkto, LinkTo :: none | pid()}
+ | {repair, Repair :: true | false | truncate}
+ | {type, Type :: dlog_type}
+ | {format, Format :: dlog_format()}
+ | {size, Size :: dlog_size()}
+ | {distributed, Nodes :: [node()]}
+ | {notify, boolean()}
+ | {head, Head :: dlog_head_opt()}
+ | {head_func, mfa()}
+ | {mode, Mode :: dlog_mode()}.
+-type dlog_options() :: [dlog_option()].
-type dlog_repair() :: 'truncate' | boolean().
-type dlog_size() :: 'infinity' | pos_integer()
- | {pos_integer(), pos_integer()}.
+ | {MaxNoBytes :: pos_integer(),
+ MaxNoFiles :: pos_integer()}.
-type dlog_status() :: 'ok' | {'blocked', 'false' | [_]}. %QueueLogRecords
-type dlog_type() :: 'halt' | 'wrap'.
@@ -75,7 +91,7 @@
%% record of args for open
-record(arg, {name = 0,
version = undefined,
- file = none :: 'none' | string(),
+ file = none :: 'none' | file:filename(),
repair = true :: dlog_repair(),
size = infinity :: dlog_size(),
type = halt :: dlog_type(),
diff --git a/lib/kernel/src/erl_boot_server.erl b/lib/kernel/src/erl_boot_server.erl
index b4c5f5e27c..0d68d3e198 100644
--- a/lib/kernel/src/erl_boot_server.erl
+++ b/lib/kernel/src/erl_boot_server.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -59,7 +59,11 @@
-type ip4_address() :: {0..255,0..255,0..255,0..255}.
--spec start(Slaves :: [atom()]) -> {'ok', pid()} | {'error', any()}.
+-spec start(Slaves) -> {'ok', Pid} | {'error', What} when
+ Slaves :: [Host],
+ Host :: atom(),
+ Pid :: pid(),
+ What :: any().
start(Slaves) ->
case check_arg(Slaves) of
@@ -69,7 +73,11 @@ start(Slaves) ->
{error, {badarg, Slaves}}
end.
--spec start_link(Slaves :: [atom()]) -> {'ok', pid()} | {'error', any()}.
+-spec start_link(Slaves) -> {'ok', Pid} | {'error', What} when
+ Slaves :: [Host],
+ Host :: atom(),
+ Pid :: pid(),
+ What :: any().
start_link(Slaves) ->
case check_arg(Slaves) of
@@ -95,7 +103,10 @@ check_arg([], Result) ->
check_arg(_, _Result) ->
error.
--spec add_slave(Slave :: atom()) -> 'ok' | {'error', any()}.
+-spec add_slave(Slave) -> 'ok' | {'error', What} when
+ Slave :: Host,
+ Host :: atom(),
+ What :: any().
add_slave(Slave) ->
case inet:getaddr(Slave, inet) of
@@ -105,7 +116,10 @@ add_slave(Slave) ->
{error, {badarg, Slave}}
end.
--spec delete_slave(Slave :: atom()) -> 'ok' | {'error', any()}.
+-spec delete_slave(Slave) -> 'ok' | {'error', What} when
+ Slave :: Host,
+ Host :: atom(),
+ What :: any().
delete_slave(Slave) ->
case inet:getaddr(Slave, inet) of
@@ -131,7 +145,9 @@ add_subnet(Mask, Addr) when is_tuple(Mask), is_tuple(Addr) ->
delete_subnet(Mask, Addr) when is_tuple(Mask), is_tuple(Addr) ->
gen_server:call(boot_server, {delete, {Mask, Addr}}).
--spec which_slaves() -> [atom()].
+-spec which_slaves() -> Slaves when
+ Slaves :: [Host],
+ Host :: atom().
which_slaves() ->
gen_server:call(boot_server, which).
diff --git a/lib/kernel/src/erl_ddll.erl b/lib/kernel/src/erl_ddll.erl
index ce64589a29..646cac99c5 100644
--- a/lib/kernel/src/erl_ddll.erl
+++ b/lib/kernel/src/erl_ddll.erl
@@ -44,14 +44,18 @@ start() ->
stop() ->
ok.
--spec load_driver(Path :: path(), Driver :: driver()) ->
- 'ok' | {'error', any()}.
+-spec load_driver(Path, Name) -> 'ok' | {'error', ErrorDesc} when
+ Path :: path(),
+ Name :: driver(),
+ ErrorDesc :: term().
load_driver(Path, Driver) ->
do_load_driver(Path, Driver, [{driver_options,[kill_ports]}]).
--spec load(Path :: path(), Driver :: driver()) ->
- 'ok' | {'error', any()}.
+-spec load(Path, Name) -> 'ok' | {'error', ErrorDesc} when
+ Path :: path(),
+ Name :: driver(),
+ ErrorDesc ::term().
load(Path, Driver) ->
do_load_driver(Path, Driver, []).
@@ -100,30 +104,41 @@ do_unload_driver(Driver,Flags) ->
end
end.
--spec unload_driver(Driver :: driver()) -> 'ok' | {'error', any()}.
+-spec unload_driver(Name) -> 'ok' | {'error', ErrorDesc} when
+ Name :: driver(),
+ ErrorDesc :: term().
unload_driver(Driver) ->
do_unload_driver(Driver,[{monitor,pending_driver},kill_ports]).
--spec unload(Driver :: driver()) -> 'ok' | {'error', any()}.
+-spec unload(Name) -> 'ok' | {'error', ErrorDesc} when
+ Name :: driver(),
+ ErrorDesc :: term().
unload(Driver) ->
do_unload_driver(Driver,[]).
--spec reload(Path :: path(), Driver :: driver()) ->
- 'ok' | {'error', any()}.
+-spec reload(Path, Name) -> 'ok' | {'error', ErrorDesc} when
+ Path :: path(),
+ Name :: driver(),
+ ErrorDesc :: pending_process | OpaqueError,
+ OpaqueError :: term().
reload(Path,Driver) ->
do_load_driver(Path, Driver, [{reload,pending_driver}]).
--spec reload_driver(Path :: path(), Driver :: driver()) ->
- 'ok' | {'error', any()}.
+-spec reload_driver(Path, Name) -> 'ok' | {'error', ErrorDesc} when
+ Path :: path(),
+ Name :: driver(),
+ ErrorDesc :: pending_process | OpaqueError,
+ OpaqueError :: term().
reload_driver(Path,Driver) ->
do_load_driver(Path, Driver, [{reload,pending_driver},
{driver_options,[kill_ports]}]).
--spec format_error(Code :: atom()) -> string().
+-spec format_error(ErrorDesc) -> string() when
+ ErrorDesc :: term().
format_error(Code) ->
case Code of
@@ -135,7 +150,10 @@ format_error(Code) ->
erl_ddll:format_error_int(Code)
end.
--spec info(Driver :: driver()) -> [{atom(), any()}, ...].
+-spec info(Name) -> InfoList when
+ Name :: driver(),
+ InfoList :: [InfoItem, ...],
+ InfoItem :: {Tag :: atom(), Value :: term()}.
info(Driver) ->
[{processes, erl_ddll:info(Driver,processes)},
@@ -146,7 +164,12 @@ info(Driver) ->
{awaiting_load, erl_ddll:info(Driver,awaiting_load)},
{awaiting_unload, erl_ddll:info(Driver,awaiting_unload)}].
--spec info() -> [{string(), [{atom(), any()}]}].
+-spec info() -> AllInfoList when
+ AllInfoList :: [DriverInfo],
+ DriverInfo :: {DriverName, InfoList},
+ DriverName :: string(),
+ InfoList :: [InfoItem],
+ InfoItem :: {Tag :: atom(), Value :: term()}.
info() ->
{ok,DriverList} = erl_ddll:loaded_drivers(),
diff --git a/lib/kernel/src/error_handler.erl b/lib/kernel/src/error_handler.erl
index 6f69f4ccb9..e1f99bf417 100644
--- a/lib/kernel/src/error_handler.erl
+++ b/lib/kernel/src/error_handler.erl
@@ -28,8 +28,11 @@
-export([undefined_function/3, undefined_lambda/3, stub_function/3,
breakpoint/3]).
--spec undefined_function(Module :: atom(), Function :: atom(), Args :: [_]) ->
- any().
+-spec undefined_function(Module, Function, Args) ->
+ any() when
+ Module :: atom(),
+ Function :: atom(),
+ Args :: list().
undefined_function(Module, Func, Args) ->
case ensure_loaded(Module) of
@@ -51,8 +54,10 @@ undefined_function(Module, Func, Args) ->
crash(Module, Func, Args)
end.
--spec undefined_lambda(Module :: atom(), Function :: fun(), Args :: [_]) ->
- any().
+-spec undefined_lambda(Module, Fun, Args) -> term() when
+ Module :: atom(),
+ Fun :: fun(),
+ Args :: list().
undefined_lambda(Module, Fun, Args) ->
case ensure_loaded(Module) of
diff --git a/lib/kernel/src/error_logger.erl b/lib/kernel/src/error_logger.erl
index cafdc52e84..f94cca000f 100644
--- a/lib/kernel/src/error_logger.erl
+++ b/lib/kernel/src/error_logger.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -69,17 +69,22 @@ start_link() ->
%% Used for simple messages; error or information.
%%-----------------------------------------------------------------
--spec error_msg(Format :: string()) -> 'ok'.
+-spec error_msg(Format) -> 'ok' when
+ Format :: string().
error_msg(Format) ->
error_msg(Format,[]).
--spec error_msg(Format :: string(), Args :: list()) -> 'ok'.
+-spec error_msg(Format, Data) -> 'ok' when
+ Format :: string(),
+ Data :: list().
error_msg(Format, Args) ->
notify({error, group_leader(), {self(), Format, Args}}).
--spec format(Format :: string(), Args :: list()) -> 'ok'.
+-spec format(Format, Data) -> 'ok' when
+ Format :: string(),
+ Data :: list().
format(Format, Args) ->
notify({error, group_leader(), {self(), Format, Args}}).
@@ -90,12 +95,18 @@ format(Format, Args) ->
%% The 'std_error' error_report type can always be used.
%%-----------------------------------------------------------------
--spec error_report(Report :: any()) -> 'ok'.
+-type report() ::
+ [{Tag :: term(), Data :: term()} | term()] | string() | term().
+
+-spec error_report(Report) -> 'ok' when
+ Report :: report().
error_report(Report) ->
error_report(std_error, Report).
--spec error_report(Type :: any(), Report :: any()) -> 'ok'.
+-spec error_report(Type, Report) -> 'ok' when
+ Type :: term(),
+ Report :: report().
error_report(Type, Report) ->
notify({error_report, group_leader(), {self(), Type, Report}}).
@@ -109,12 +120,15 @@ error_report(Type, Report) ->
%% mapped to std_info or std_error accordingly.
%%-----------------------------------------------------------------
--spec warning_report(Report :: any()) -> 'ok'.
+-spec warning_report(Report) -> 'ok' when
+ Report :: report().
warning_report(Report) ->
warning_report(std_warning, Report).
--spec warning_report(Type :: any(), Report :: any()) -> 'ok'.
+-spec warning_report(Type, Report) -> 'ok' when
+ Type :: any(),
+ Report :: report().
warning_report(Type, Report) ->
{Tag, NType} = case error_logger:warning_map() of
@@ -143,12 +157,15 @@ warning_report(Type, Report) ->
%% other types of reports.
%%-----------------------------------------------------------------
--spec warning_msg(Format :: string()) -> 'ok'.
+-spec warning_msg(Format) -> 'ok' when
+ Format :: string().
warning_msg(Format) ->
warning_msg(Format,[]).
--spec warning_msg(Format :: string(), Args :: list()) -> 'ok'.
+-spec warning_msg(Format, Data) -> 'ok' when
+ Format :: string(),
+ Data :: list().
warning_msg(Format, Args) ->
Tag = case error_logger:warning_map() of
@@ -167,12 +184,15 @@ warning_msg(Format, Args) ->
%% The 'std_info' info_report type can always be used.
%%-----------------------------------------------------------------
--spec info_report(Report :: any()) -> 'ok'.
+-spec info_report(Report) -> 'ok' when
+ Report :: report().
info_report(Report) ->
info_report(std_info, Report).
--spec info_report(Type :: any(), Report :: any()) -> 'ok'.
+-spec info_report(Type, Report) -> 'ok' when
+ Type :: any(),
+ Report :: report().
info_report(Type, Report) ->
notify({info_report, group_leader(), {self(), Type, Report}}).
@@ -182,12 +202,15 @@ info_report(Type, Report) ->
%% information messages.
%%-----------------------------------------------------------------
--spec info_msg(Format :: string()) -> 'ok'.
+-spec info_msg(Format) -> 'ok' when
+ Format :: string().
info_msg(Format) ->
info_msg(Format,[]).
--spec info_msg(Format :: string(), Args :: list()) -> 'ok'.
+-spec info_msg(Format, Data) -> 'ok' when
+ Format :: string(),
+ Data :: list().
info_msg(Format, Args) ->
notify({info_msg, group_leader(), {self(), Format, Args}}).
@@ -223,17 +246,23 @@ swap_handler(silent) ->
swap_handler(false) ->
ok. % keep primitive event handler as-is
--spec add_report_handler(Module :: atom()) -> any().
+-spec add_report_handler(Handler) -> any() when
+ Handler :: module().
add_report_handler(Module) when is_atom(Module) ->
gen_event:add_handler(error_logger, Module, []).
--spec add_report_handler(atom(), any()) -> any().
+-spec add_report_handler(Handler, Args) -> Result when
+ Handler :: module(),
+ Args :: gen_event:handler_args(),
+ Result :: gen_event:add_handler_ret().
add_report_handler(Module, Args) when is_atom(Module) ->
gen_event:add_handler(error_logger, Module, Args).
--spec delete_report_handler(Module :: atom()) -> any().
+-spec delete_report_handler(Handler) -> Result when
+ Handler :: module(),
+ Result :: gen_event:del_handler_ret().
delete_report_handler(Module) when is_atom(Module) ->
gen_event:delete_handler(error_logger, Module, []).
@@ -250,9 +279,16 @@ simple_logger() ->
%% Log all errors to File for all eternity
--spec logfile(Request :: {'open', string()}) -> 'ok' | {'error',any()}
- ; (Request :: 'close') -> 'ok' | {'error', any()}
- ; (Request :: 'filename') -> atom() | string() | {'error', any()}.
+-type open_error() :: file:posix() | badarg | system_limit.
+
+-spec logfile(Request :: {open, Filename}) -> ok | {error, OpenReason} when
+ Filename ::file:name(),
+ OpenReason :: allready_have_logfile | open_error()
+ ; (Request :: close) -> ok | {error, CloseReason} when
+ CloseReason :: module_not_found
+ ; (Request :: filename) -> Filename | {error, FilenameReason} when
+ Filename :: file:name(),
+ FilenameReason :: no_log_file.
logfile({open, File}) ->
case lists:member(error_logger_file_h,
@@ -280,7 +316,8 @@ logfile(filename) ->
%% Possibly turn off all tty printouts, maybe we only want the errors
%% to go to a file
--spec tty(Flag :: boolean()) -> 'ok'.
+-spec tty(Flag) -> 'ok' when
+ Flag :: boolean().
tty(true) ->
Hs = gen_event:which_handlers(error_logger),
diff --git a/lib/kernel/src/file.erl b/lib/kernel/src/file.erl
index 88bcf9a9cc..f1a8aa9f77 100644
--- a/lib/kernel/src/file.erl
+++ b/lib/kernel/src/file.erl
@@ -79,15 +79,19 @@
-type file_info() :: #file_info{}.
-type fd() :: #file_descriptor{}.
-type io_device() :: pid() | fd().
--type location() :: integer() | {'bof', integer()} | {'cur', integer()}
- | {'eof', integer()} | 'bof' | 'cur' | 'eof'.
+-type location() :: integer() | {'bof', Offset :: integer()}
+ | {'cur', Offset :: integer()}
+ | {'eof', Offset :: integer()} | 'bof' | 'cur' | 'eof'.
-type mode() :: 'read' | 'write' | 'append'
| 'exclusive' | 'raw' | 'binary'
- | {'delayed_write', non_neg_integer(), non_neg_integer()}
- | 'delayed_write' | {'read_ahead', pos_integer()}
+ | {'delayed_write',
+ Size :: non_neg_integer(),
+ Delay :: non_neg_integer()}
+ | 'delayed_write' | {'read_ahead', Size :: pos_integer()}
| 'read_ahead' | 'compressed'
| {'encoding', unicode:encoding()}.
--type name() :: string() | atom() | [name()] | binary().
+-type deep_list() :: [char() | atom() | deep_list()].
+-type name() :: string() | atom() | deep_list() | (RawFilename :: binary()).
-type posix() :: 'eacces' | 'eagain' | 'ebadf' | 'ebusy' | 'edquot'
| 'eexist' | 'efault' | 'efbig' | 'eintr' | 'einval'
| 'eio' | 'eisdir' | 'eloop' | 'emfile' | 'emlink'
@@ -96,10 +100,14 @@
| 'enotblk' | 'enotdir' | 'enotsup' | 'enxio' | 'eperm'
| 'epipe' | 'erofs' | 'espipe' | 'esrch' | 'estale'
| 'exdev'.
--type bindings() :: any().
-
--type date() :: {pos_integer(), pos_integer(), pos_integer()}.
--type time() :: {non_neg_integer(), non_neg_integer(), non_neg_integer()}.
+-type bindings() :: erl_eval:binding_struct().
+
+-type date() :: {Year :: pos_integer(),
+ Month :: pos_integer(),
+ Day ::pos_integer()}.
+-type time() :: {Hour :: non_neg_integer(),
+ Minute :: non_neg_integer(),
+ Second :: non_neg_integer()}.
-type date_time() :: {date(), time()}.
-type posix_file_advise() :: 'normal' | 'sequential' | 'random'
| 'no_reuse' | 'will_need' | 'dont_need'.
@@ -107,8 +115,10 @@
%%%-----------------------------------------------------------------
%%% General functions
--spec format_error(Reason :: posix() | {integer(), atom(), any()}) ->
- string().
+-spec format_error(Reason) -> Chars when
+ Reason :: posix() | badarg | terminated | system_limit
+ | {Line :: integer(), Mod :: module(), Term :: term()},
+ Chars :: string().
format_error({_Line, ?MODULE, undefined_script}) ->
"no value returned from script";
@@ -129,7 +139,9 @@ format_error(terminated) ->
format_error(ErrorId) ->
erl_posix_msg:message(ErrorId).
--spec pid2name(Pid :: pid()) -> {'ok', filename()} | 'undefined'.
+-spec pid2name(Pid) -> {ok, Filename} | undefined when
+ Filename :: filename(),
+ Pid :: pid().
pid2name(Pid) when is_pid(Pid) ->
case whereis(?FILE_SERVER) of
@@ -148,42 +160,61 @@ pid2name(Pid) when is_pid(Pid) ->
%%% File server functions.
%%% Functions that do not operate on a single open file.
%%% Stateless.
--spec get_cwd() -> {'ok', filename()} | {'error', posix()}.
+-spec get_cwd() -> {ok, Dir} | {error, Reason} when
+ Dir :: filename(),
+ Reason :: posix().
get_cwd() ->
call(get_cwd, []).
--spec get_cwd(Drive :: string()) -> {'ok', filename()} | {'error', posix()}.
+-spec get_cwd(Drive) -> {ok, Dir} | {error, Reason} when
+ Drive :: string(),
+ Dir :: filename(),
+ Reason :: posix() | badarg.
get_cwd(Drive) ->
check_and_call(get_cwd, [file_name(Drive)]).
--spec set_cwd(Dirname :: name()) -> 'ok' | {'error', posix()}.
+-spec set_cwd(Dir) -> ok | {error, Reason} when
+ Dir :: name(),
+ Reason :: posix() | badarg.
set_cwd(Dirname) ->
check_and_call(set_cwd, [file_name(Dirname)]).
--spec delete(Name :: name()) -> 'ok' | {'error', posix()}.
+-spec delete(Filename) -> ok | {error, Reason} when
+ Filename :: name(),
+ Reason :: posix() | badarg.
delete(Name) ->
check_and_call(delete, [file_name(Name)]).
--spec rename(From :: name(), To :: name()) -> 'ok' | {'error', posix()}.
+-spec rename(Source, Destination) -> ok | {error, Reason} when
+ Source :: name(),
+ Destination :: name(),
+ Reason :: posix() | badarg.
rename(From, To) ->
check_and_call(rename, [file_name(From), file_name(To)]).
--spec make_dir(Name :: name()) -> 'ok' | {'error', posix()}.
+-spec make_dir(Dir) -> ok | {error, Reason} when
+ Dir :: name(),
+ Reason :: posix() | badarg.
make_dir(Name) ->
check_and_call(make_dir, [file_name(Name)]).
--spec del_dir(Name :: name()) -> 'ok' | {'error', posix()}.
+-spec del_dir(Dir) -> ok | {error, Reason} when
+ Dir :: name(),
+ Reason :: posix() | badarg.
del_dir(Name) ->
check_and_call(del_dir, [file_name(Name)]).
--spec read_file_info(Name :: name()) -> {'ok', file_info()} | {'error', posix()}.
+-spec read_file_info(Filename) -> {ok, FileInfo} | {error, Reason} when
+ Filename :: name(),
+ FileInfo :: file_info(),
+ Reason :: posix() | badarg.
read_file_info(Name) ->
check_and_call(read_file_info, [file_name(Name)]).
@@ -193,45 +224,66 @@ read_file_info(Name) ->
altname(Name) ->
check_and_call(altname, [file_name(Name)]).
--spec read_link_info(Name :: name()) -> {'ok', file_info()} | {'error', posix()}.
+-spec read_link_info(Name) -> {ok, FileInfo} | {error, Reason} when
+ Name :: name(),
+ FileInfo :: file_info(),
+ Reason :: posix() | badarg.
read_link_info(Name) ->
check_and_call(read_link_info, [file_name(Name)]).
--spec read_link(Name :: name()) -> {'ok', filename()} | {'error', posix()}.
+-spec read_link(Name) -> {ok, Filename} | {error, Reason} when
+ Name :: name(),
+ Filename :: filename(),
+ Reason :: posix() | badarg.
read_link(Name) ->
check_and_call(read_link, [file_name(Name)]).
--spec write_file_info(Name :: name(), Info :: file_info()) ->
- 'ok' | {'error', posix()}.
+-spec write_file_info(Filename, FileInfo) -> ok | {error, Reason} when
+ Filename :: name(),
+ FileInfo :: file_info(),
+ Reason :: posix() | badarg.
write_file_info(Name, Info = #file_info{}) ->
check_and_call(write_file_info, [file_name(Name), Info]).
--spec list_dir(Name :: name()) -> {'ok', [filename()]} | {'error', posix()}.
+-spec list_dir(Dir) -> {ok, Filenames} | {error, Reason} when
+ Dir :: name(),
+ Filenames :: [filename()],
+ Reason :: posix() | badarg.
list_dir(Name) ->
check_and_call(list_dir, [file_name(Name)]).
--spec read_file(Name :: name()) ->
- {'ok', binary()} | {'error', posix() | 'terminated' | 'system_limit'}.
+-spec read_file(Filename) -> {ok, Binary} | {error, Reason} when
+ Filename :: name(),
+ Binary :: binary(),
+ Reason :: posix() | badarg | terminated | system_limit.
read_file(Name) ->
check_and_call(read_file, [file_name(Name)]).
--spec make_link(Old :: name(), New :: name()) -> 'ok' | {'error', posix()}.
+-spec make_link(Existing, New) -> ok | {error, Reason} when
+ Existing :: name(),
+ New :: name(),
+ Reason :: posix() | badarg.
make_link(Old, New) ->
check_and_call(make_link, [file_name(Old), file_name(New)]).
--spec make_symlink(Old :: name(), New :: name()) -> 'ok' | {'error', posix()}.
+-spec make_symlink(Name1, Name2) -> ok | {error, Reason} when
+ Name1 :: name(),
+ Name2 :: name(),
+ Reason :: posix() | badarg.
make_symlink(Old, New) ->
check_and_call(make_symlink, [file_name(Old), file_name(New)]).
--spec write_file(Name :: name(), Bin :: iodata()) ->
- 'ok' | {'error', posix() | 'terminated' | 'system_limit'}.
+-spec write_file(Filename, Bytes) -> ok | {error, Reason} when
+ Filename :: name(),
+ Bytes :: iodata(),
+ Reason :: posix() | badarg | terminated | system_limit.
write_file(Name, Bin) ->
check_and_call(write_file, [file_name(Name), make_binary(Bin)]).
@@ -240,8 +292,11 @@ write_file(Name, Bin) ->
%% when it is time to change file server protocol again.
%% Meanwhile, it is implemented here, slightly less efficient.
--spec write_file(Name :: name(), Bin :: iodata(), Modes :: [mode()]) ->
- 'ok' | {'error', posix()}.
+-spec write_file(Filename, Bytes, Modes) -> ok | {error, Reason} when
+ Filename :: name(),
+ Bytes :: iodata(),
+ Modes :: [mode()],
+ Reason :: posix() | badarg | terminated | system_limit.
write_file(Name, Bin, ModeList) when is_list(ModeList) ->
case make_binary(Bin) of
@@ -295,8 +350,11 @@ raw_write_file_info(Name, #file_info{} = Info) ->
%% Contemporary mode specification - list of options
--spec open(Name :: name(), Modes :: [mode()]) ->
- {'ok', io_device()} | {'error', posix() | 'system_limit'}.
+-spec open(Filename, Modes) -> {ok, IoDevice} | {error, Reason} when
+ Filename :: name(),
+ Modes :: [mode()],
+ IoDevice :: io_device(),
+ Reason :: posix() | badarg | system_limit.
open(Item, ModeList) when is_list(ModeList) ->
case lists:member(raw, ModeList) of
@@ -349,7 +407,9 @@ open(Item, Mode) ->
%%% The File argument must be either a Pid or a handle
%%% returned from ?PRIM_FILE:open.
--spec close(File :: io_device()) -> 'ok' | {'error', posix() | 'terminated'}.
+-spec close(IoDevice) -> ok | {error, Reason} when
+ IoDevice :: io_device(),
+ Reason :: posix() | badarg | terminated.
close(File) when is_pid(File) ->
R = file_request(File, close),
@@ -367,9 +427,12 @@ close(#file_descriptor{module = Module} = Handle) ->
close(_) ->
{error, badarg}.
--spec advise(File :: io_device(), Offset :: integer(),
- Length :: integer(), Advise :: posix_file_advise()) ->
- 'ok' | {'error', posix()}.
+-spec advise(IoDevice, Offset, Length, Advise) -> ok | {error, Reason} when
+ IoDevice :: io_device(),
+ Offset :: integer(),
+ Length :: integer(),
+ Advise :: posix_file_advise(),
+ Reason :: posix() | badarg.
advise(File, Offset, Length, Advise) when is_pid(File) ->
R = file_request(File, {advise, Offset, Length, Advise}),
@@ -379,8 +442,11 @@ advise(#file_descriptor{module = Module} = Handle, Offset, Length, Advise) ->
advise(_, _, _, _) ->
{error, badarg}.
--spec read(File :: io_device() | atom(), Size :: non_neg_integer()) ->
- 'eof' | {'ok', [char()] | binary()} | {'error', posix()}.
+-spec read(IoDevice, Number) -> {ok, Data} | eof | {error, Reason} when
+ IoDevice :: io_device() | atom(),
+ Number :: non_neg_integer(),
+ Data :: string() | binary(),
+ Reason :: posix() | badarg | terminated.
read(File, Sz) when (is_pid(File) orelse is_atom(File)), is_integer(Sz), Sz >= 0 ->
case io:request(File, {get_chars, '', Sz}) of
@@ -395,8 +461,10 @@ read(#file_descriptor{module = Module} = Handle, Sz)
read(_, _) ->
{error, badarg}.
--spec read_line(File :: io_device() | atom()) ->
- 'eof' | {'ok', [char()] | binary()} | {'error', posix()}.
+-spec read_line(IoDevice) -> {ok, Data} | eof | {error, Reason} when
+ IoDevice :: io_device() | atom(),
+ Data :: string() | binary(),
+ Reason :: posix() | badarg | terminated.
read_line(File) when (is_pid(File) orelse is_atom(File)) ->
case io:request(File, {get_line, ''}) of
@@ -410,9 +478,12 @@ read_line(#file_descriptor{module = Module} = Handle) ->
read_line(_) ->
{error, badarg}.
--spec pread(File :: io_device(),
- LocationNumbers :: [{location(), non_neg_integer()}]) ->
- {'ok', [string() | binary() | 'eof']} | {'error', posix()}.
+-spec pread(IoDevice, LocNums) -> {ok, DataL} | eof | {error, Reason} when
+ IoDevice :: io_device(),
+ LocNums :: [{Location :: location(), Number :: non_neg_integer()}],
+ DataL :: [Data],
+ Data :: string() | binary() | eof,
+ Reason :: posix() | badarg | terminated.
pread(File, L) when is_pid(File), is_list(L) ->
pread_int(File, L, []);
@@ -435,10 +506,13 @@ pread_int(File, [{At, Sz} | T], R) when is_integer(Sz), Sz >= 0 ->
pread_int(_, _, _) ->
{error, badarg}.
--spec pread(File :: io_device(),
- Location :: location(),
- Size :: non_neg_integer()) ->
- 'eof' | {'ok', string() | binary()} | {'error', posix()}.
+-spec pread(IoDevice, Location, Number) ->
+ {ok, Data} | eof | {error, Reason} when
+ IoDevice :: io_device(),
+ Location :: location(),
+ Number :: non_neg_integer(),
+ Data :: string() | binary(),
+ Reason :: posix() | badarg | terminated.
pread(File, At, Sz) when is_pid(File), is_integer(Sz), Sz >= 0 ->
R = file_request(File, {pread, At, Sz}),
@@ -449,8 +523,10 @@ pread(#file_descriptor{module = Module} = Handle, Offs, Sz)
pread(_, _, _) ->
{error, badarg}.
--spec write(File :: io_device() | atom(), Byte :: iodata()) ->
- 'ok' | {'error', posix() | 'terminated'}.
+-spec write(IoDevice, Bytes) -> ok | {error, Reason} when
+ IoDevice :: io_device() | atom(),
+ Bytes :: iodata(),
+ Reason :: posix() | badarg | terminated.
write(File, Bytes) when (is_pid(File) orelse is_atom(File)) ->
case make_binary(Bytes) of
@@ -464,8 +540,11 @@ write(#file_descriptor{module = Module} = Handle, Bytes) ->
write(_, _) ->
{error, badarg}.
--spec pwrite(File :: io_device(), L :: [{location(), iodata()}]) ->
- 'ok' | {'error', {non_neg_integer(), posix()}}.
+-spec pwrite(IoDevice, LocBytes) -> ok | {error, {N, Reason}} when
+ IoDevice :: io_device(),
+ LocBytes :: [{Location :: location(), Bytes :: iodata()}],
+ N :: non_neg_integer(),
+ Reason :: posix() | badarg | terminated.
pwrite(File, L) when is_pid(File), is_list(L) ->
pwrite_int(File, L, 0);
@@ -486,10 +565,11 @@ pwrite_int(File, [{At, Bytes} | T], R) ->
pwrite_int(_, _, _) ->
{error, badarg}.
--spec pwrite(File :: io_device(),
- Location :: location(),
- Bytes :: iodata()) ->
- 'ok' | {'error', posix()}.
+-spec pwrite(IoDevice, Location, Bytes) -> ok | {error, Reason} when
+ IoDevice :: io_device(),
+ Location :: location(),
+ Bytes :: iodata(),
+ Reason :: posix() | badarg | terminated.
pwrite(File, At, Bytes) when is_pid(File) ->
R = file_request(File, {pwrite, At, Bytes}),
@@ -499,7 +579,9 @@ pwrite(#file_descriptor{module = Module} = Handle, Offs, Bytes) ->
pwrite(_, _, _) ->
{error, badarg}.
--spec datasync(File :: io_device()) -> 'ok' | {'error', posix()}.
+-spec datasync(IoDevice) -> ok | {error, Reason} when
+ IoDevice :: io_device(),
+ Reason :: posix() | badarg | terminated.
datasync(File) when is_pid(File) ->
R = file_request(File, datasync),
@@ -509,7 +591,9 @@ datasync(#file_descriptor{module = Module} = Handle) ->
datasync(_) ->
{error, badarg}.
--spec sync(File :: io_device()) -> 'ok' | {'error', posix()}.
+-spec sync(IoDevice) -> ok | {error, Reason} when
+ IoDevice :: io_device(),
+ Reason :: posix() | badarg | terminated.
sync(File) when is_pid(File) ->
R = file_request(File, sync),
@@ -519,8 +603,11 @@ sync(#file_descriptor{module = Module} = Handle) ->
sync(_) ->
{error, badarg}.
--spec position(File :: io_device(), Location :: location()) ->
- {'ok',integer()} | {'error', posix()}.
+-spec position(IoDevice, Location) -> {ok, NewPosition} | {error, Reason} when
+ IoDevice :: io_device(),
+ Location :: location(),
+ NewPosition :: integer(),
+ Reason :: posix() | badarg | terminated.
position(File, At) when is_pid(File) ->
R = file_request(File, {position,At}),
@@ -530,7 +617,9 @@ position(#file_descriptor{module = Module} = Handle, At) ->
position(_, _) ->
{error, badarg}.
--spec truncate(File :: io_device()) -> 'ok' | {'error', posix()}.
+-spec truncate(IoDevice) -> ok | {error, Reason} when
+ IoDevice :: io_device(),
+ Reason :: posix() | badarg | terminated.
truncate(File) when is_pid(File) ->
R = file_request(File, truncate),
@@ -540,17 +629,26 @@ truncate(#file_descriptor{module = Module} = Handle) ->
truncate(_) ->
{error, badarg}.
--spec copy(Source :: io_device() | name() | {name(), [mode()]},
- Destination :: io_device() | name() | {name(), [mode()]}) ->
- {'ok', non_neg_integer()} | {'error', posix()}.
+-spec copy(Source, Destination) -> {ok, BytesCopied} | {error, Reason} when
+ Source :: io_device() | Filename | {Filename, Modes},
+ Destination :: io_device() | Filename | {Filename, Modes},
+ Filename :: name(),
+ Modes :: [mode()],
+ BytesCopied :: non_neg_integer(),
+ Reason :: posix() | badarg | terminated.
copy(Source, Dest) ->
copy_int(Source, Dest, infinity).
--spec copy(Source :: io_device() | name() | {name(), [mode()]},
- Destination :: io_device() | name() | {name(), [mode()]},
- Length :: non_neg_integer() | 'infinity') ->
- {'ok', non_neg_integer()} | {'error', posix()}.
+-spec copy(Source, Destination, ByteCount) ->
+ {ok, BytesCopied} | {error, Reason} when
+ Source :: io_device() | Filename | {Filename, Modes},
+ Destination :: io_device() | Filename | {Filename, Modes},
+ Filename :: name(),
+ Modes :: [mode()],
+ ByteCount :: non_neg_integer() | infinity,
+ BytesCopied :: non_neg_integer(),
+ Reason :: posix() | badarg | terminated.
copy(Source, Dest, Length)
when is_integer(Length), Length >= 0;
@@ -772,8 +870,11 @@ ipread_s32bu_p32bu_2(File,
%%% The following functions, built upon the other interface functions,
%%% provide a higher-lever interface to files.
--spec consult(File :: name()) ->
- {'ok', list()} | {'error', posix() | {integer(), atom(), any()}}.
+-spec consult(Filename) -> {ok, Terms} | {error, Reason} when
+ Filename :: name(),
+ Terms :: [term()],
+ Reason :: posix() | badarg | terminated | system_limit
+ | {Line :: integer(), Mod :: module(), Term :: term()}.
consult(File) ->
case open(File, [read]) of
@@ -785,8 +886,14 @@ consult(File) ->
Error
end.
--spec path_consult(Paths :: [name()], File :: name()) ->
- {'ok', list(), filename()} | {'error', posix() | {integer(), atom(), any()}}.
+-spec path_consult(Path, Filename) -> {ok, Terms, FullName} | {error, Reason} when
+ Path :: [Dir],
+ Dir :: name(),
+ Filename :: name(),
+ Terms :: [term()],
+ FullName :: filename(),
+ Reason :: posix() | badarg | terminated | system_limit
+ | {Line :: integer(), Mod :: module(), Term :: term()}.
path_consult(Path, File) ->
case path_open(Path, File, [read]) of
@@ -803,13 +910,19 @@ path_consult(Path, File) ->
E2
end.
--spec eval(File :: name()) -> 'ok' | {'error', posix()}.
+-spec eval(Filename) -> ok | {error, Reason} when
+ Filename :: name(),
+ Reason :: posix() | badarg | terminated | system_limit
+ | {Line :: integer(), Mod :: module(), Term :: term()}.
eval(File) ->
eval(File, erl_eval:new_bindings()).
--spec eval(File :: name(), Bindings :: bindings()) ->
- 'ok' | {'error', posix()}.
+-spec eval(Filename, Bindings) -> ok | {error, Reason} when
+ Filename :: name(),
+ Bindings :: bindings(),
+ Reason :: posix() | badarg | terminated | system_limit
+ | {Line :: integer(), Mod :: module(), Term :: term()}.
eval(File, Bs) ->
case open(File, [read]) of
@@ -821,14 +934,24 @@ eval(File, Bs) ->
Error
end.
--spec path_eval(Paths :: [name()], File :: name()) ->
- {'ok', filename()} | {'error', posix() | {integer(), atom(), any()}}.
+-spec path_eval(Path, Filename) -> {ok, FullName} | {error, Reason} when
+ Path :: [Dir :: name()],
+ Filename :: name(),
+ FullName :: filename(),
+ Reason :: posix() | badarg | terminated | system_limit
+ | {Line :: integer(), Mod :: module(), Term :: term()}.
path_eval(Path, File) ->
path_eval(Path, File, erl_eval:new_bindings()).
--spec path_eval(Paths :: [name()], File :: name(), Bindings :: bindings()) ->
- {'ok', filename()} | {'error', posix() | {integer(), atom(), any()}}.
+-spec path_eval(Path, Filename, Bindings) ->
+ {ok, FullName} | {error, Reason} when
+ Path :: [Dir :: name()],
+ Filename :: name(),
+ Bindings :: bindings(),
+ FullName :: filename(),
+ Reason :: posix() | badarg | terminated | system_limit
+ | {Line :: integer(), Mod :: module(), Term :: term()}.
path_eval(Path, File, Bs) ->
case path_open(Path, File, [read]) of
@@ -845,14 +968,21 @@ path_eval(Path, File, Bs) ->
E2
end.
--spec script(File :: name()) ->
- {'ok', any()} | {'error', posix() | {integer(), atom(), any()}}.
+-spec script(Filename) -> {ok, Value} | {error, Reason} when
+ Filename :: name(),
+ Value :: term(),
+ Reason :: posix() | badarg | terminated | system_limit
+ | {Line :: integer(), Mod :: module(), Term :: term()}.
script(File) ->
script(File, erl_eval:new_bindings()).
--spec script(File :: name(), Bindings :: bindings()) ->
- {'ok', any()} | {'error', posix() | {integer(), atom(), any()}}.
+-spec script(Filename, Bindings) -> {ok, Value} | {error, Reason} when
+ Filename :: name(),
+ Bindings :: bindings(),
+ Value :: term(),
+ Reason :: posix() | badarg | terminated | system_limit
+ | {Line :: integer(), Mod :: module(), Term :: term()}.
script(File, Bs) ->
case open(File, [read]) of
@@ -864,16 +994,27 @@ script(File, Bs) ->
Error
end.
--spec path_script/2 :: (Paths :: [name()], File :: name()) ->
- {'ok', term(), filename()} | {'error', posix() | {integer(), atom(), _}}.
+-spec path_script(Path, Filename) ->
+ {ok, Value, FullName} | {error, Reason} when
+ Path :: [Dir :: name()],
+ Filename :: name(),
+ Value :: term(),
+ FullName :: filename(),
+ Reason :: posix() | badarg | terminated | system_limit
+ | {Line :: integer(), Mod :: module(), Term :: term()}.
path_script(Path, File) ->
path_script(Path, File, erl_eval:new_bindings()).
--spec path_script(Paths :: [name()],
- File :: name(),
- Bindings :: bindings()) ->
- {'ok', term(), filename()} | {'error', posix() | {integer(), atom(), _}}.
+-spec path_script(Path, Filename, Bindings) ->
+ {ok, Value, FullName} | {error, Reason} when
+ Path :: [Dir :: name()],
+ Filename :: name(),
+ Bindings :: bindings(),
+ Value :: term(),
+ FullName :: filename(),
+ Reason :: posix() | badarg | terminated | system_limit
+ | {Line :: integer(), Mod :: module(), Term :: term()}.
path_script(Path, File, Bs) ->
case path_open(Path, File, [read]) of
@@ -898,8 +1039,14 @@ path_script(Path, File, Bs) ->
%% Searches the Paths for file Filename which can be opened with Mode.
%% The path list is ignored if Filename contains an absolute path.
--spec path_open(Paths :: [name()], Name :: name(), Modes :: [mode()]) ->
- {'ok', io_device(), filename()} | {'error', posix()}.
+-spec path_open(Path, Filename, Modes) ->
+ {ok, IoDevice, FullName} | {error, Reason} when
+ Path :: [Dir :: name()],
+ Filename :: name(),
+ Modes :: [mode()],
+ IoDevice :: io_device(),
+ FullName :: filename(),
+ Reason :: posix() | badarg | system_limit.
path_open(PathList, Name, Mode) ->
case file_name(Name) of
@@ -919,47 +1066,57 @@ path_open(PathList, Name, Mode) ->
end
end.
--spec change_mode(Name :: name(), Mode :: integer()) ->
- 'ok' | {'error', posix()}.
+-spec change_mode(Filename, Mode) -> ok | {error, Reason} when
+ Filename :: name(),
+ Mode :: integer(),
+ Reason :: posix() | badarg.
change_mode(Name, Mode)
when is_integer(Mode) ->
write_file_info(Name, #file_info{mode=Mode}).
--spec change_owner(Name :: name(), OwnerId :: integer()) ->
- 'ok' | {'error', posix()}.
+-spec change_owner(Filename, Uid) -> ok | {error, Reason} when
+ Filename :: name(),
+ Uid :: integer(),
+ Reason :: posix() | badarg.
change_owner(Name, OwnerId)
when is_integer(OwnerId) ->
write_file_info(Name, #file_info{uid=OwnerId}).
--spec change_owner(Name :: name(),
- OwnerId :: integer(),
- GroupId :: integer()) ->
- 'ok' | {'error', posix()}.
+-spec change_owner(Filename, Uid, Gid) -> ok | {error, Reason} when
+ Filename :: name(),
+ Uid :: integer(),
+ Gid :: integer(),
+ Reason :: posix() | badarg.
change_owner(Name, OwnerId, GroupId)
when is_integer(OwnerId), is_integer(GroupId) ->
write_file_info(Name, #file_info{uid=OwnerId, gid=GroupId}).
--spec change_group(Name :: name(), GroupId :: integer()) ->
- 'ok' | {'error', posix()}.
+-spec change_group(Filename, Gid) -> ok | {error, Reason} when
+ Filename :: name(),
+ Gid :: integer(),
+ Reason :: posix() | badarg.
change_group(Name, GroupId)
when is_integer(GroupId) ->
write_file_info(Name, #file_info{gid=GroupId}).
--spec change_time(Name :: name(), Time :: date_time()) ->
- 'ok' | {'error', posix()}.
+-spec change_time(Filename, Mtime) -> ok | {error, Reason} when
+ Filename :: name(),
+ Mtime :: date_time(),
+ Reason :: posix() | badarg.
change_time(Name, Time)
when is_tuple(Time) ->
write_file_info(Name, #file_info{mtime=Time}).
--spec change_time(Name :: name(),
- ATime :: date_time(),
- MTime :: date_time()) ->
- 'ok' | {'error', posix()}.
+-spec change_time(Filename, Atime, Mtime) -> ok | {error, Reason} when
+ Filename :: name(),
+ Atime :: date_time(),
+ Mtime :: date_time(),
+ Reason :: posix() | badarg.
change_time(Name, Atime, Mtime)
when is_tuple(Atime), is_tuple(Mtime) ->
diff --git a/lib/kernel/src/gen_sctp.erl b/lib/kernel/src/gen_sctp.erl
index cccfa75005..004f03f231 100644
--- a/lib/kernel/src/gen_sctp.erl
+++ b/lib/kernel/src/gen_sctp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -33,11 +33,57 @@
-export([error_string/1]).
-export([controlling_process/2]).
-
+-opaque assoc_id() :: term().
+-type hostname() :: inet:hostname().
+-type ip_address() :: inet:ip_address().
+-type port_number() :: 0..65535.
+-type posix() :: inet:posix().
+-type sctp_option() ::
+ {mode, list | binary} | list | binary
+ | {active, true | false | once}
+ | {buffer, non_neg_integer()}
+ | {tos, integer()}
+ | {priority, integer()}
+ | {dontroute, boolean()}
+ | {reuseaddr, boolean()}
+ | {linger, {boolean(), non_neg_integer()}}
+ | {sndbuf, non_neg_integer()}
+ | {recbuf, non_neg_integer()}
+ | {sctp_rtoinfo, #sctp_rtoinfo{}}
+ | {sctp_associnfo, #sctp_assocparams{}}
+ | {sctp_initmsg, #sctp_initmsg{}}
+ | {sctp_autoclose, timeout()}
+ | {sctp_nodelay, boolean()}
+ | {sctp_disable_fragments, boolean()}
+ | {sctp_i_want_mapped_v4_addr, boolean()}
+ | {sctp_maxseg, non_neg_integer()}
+ | {sctp_primary_addr, #sctp_prim{}}
+ | {sctp_set_peer_primary_addr, #sctp_setpeerprim{}}
+ | {sctp_adaptation_layer, #sctp_setadaptation{}}
+ | {sctp_peer_addr_params, #sctp_paddrparams{}}
+ | {sctp_default_send_param, #sctp_sndrcvinfo{}}
+ | {sctp_events, #sctp_event_subscribe{}}
+ | {sctp_delayed_ack_time, #sctp_assoc_value{}}
+ | {sctp_status, #sctp_status{}}
+ | {sctp_get_peer_addr_info, #sctp_paddrinfo{}}.
+-opaque sctp_socket() :: port().
+
+-spec open() -> {ok, Socket} | {error, posix()} when
+ Socket :: sctp_socket().
open() ->
open([]).
+-spec open(Port) -> {ok, Socket} | {error, posix()} when
+ Port :: port_number(),
+ Socket :: sctp_socket();
+ (Opts) -> {ok, Socket} | {error, posix()} when
+ Opts :: [Opt],
+ Opt :: {ip,IP} | {ifaddr,IP} | {port,Port} | sctp_option(),
+ IP :: ip_address() | any | loopback,
+ Port :: port_number(),
+ Socket :: sctp_socket().
+
open(Opts) when is_list(Opts) ->
Mod = mod(Opts, undefined),
case Mod:open(Opts) of
@@ -52,11 +98,21 @@ open(Port) when is_integer(Port) ->
open(X) ->
erlang:error(badarg, [X]).
+-spec open(Port, Opts) -> {ok, Socket} | {error, posix()} when
+ Opts :: [Opt],
+ Opt :: {ip,IP} | {ifaddr,IP} | {port,Port} | sctp_option(),
+ IP :: ip_address() | any | loopback,
+ Port :: port_number(),
+ Socket :: sctp_socket().
+
open(Port, Opts) when is_integer(Port), is_list(Opts) ->
open([{port,Port}|Opts]);
open(Port, Opts) ->
erlang:error(badarg, [Port,Opts]).
+-spec close(Socket) -> ok | {error, posix()} when
+ Socket :: sctp_socket().
+
close(S) when is_port(S) ->
case inet_db:lookup_socket(S) of
{ok,Mod} ->
@@ -68,6 +124,11 @@ close(S) ->
+-spec listen(Socket, IsServer) -> ok | {error, Reason} when
+ Socket :: sctp_socket(),
+ IsServer :: boolean(),
+ Reason :: term().
+
listen(S, Flag) when is_port(S), is_boolean(Flag) ->
case inet_db:lookup_socket(S) of
{ok,Mod} ->
@@ -77,9 +138,25 @@ listen(S, Flag) when is_port(S), is_boolean(Flag) ->
listen(S, Flag) ->
erlang:error(badarg, [S,Flag]).
+-spec connect(Socket, Addr, Port, Opts) -> {ok, Assoc} | {error, posix()} when
+ Socket :: sctp_socket(),
+ Addr :: ip_address() | hostname(),
+ Port :: port_number(),
+ Opts :: [Opt :: sctp_option()],
+ Assoc :: #sctp_assoc_change{}.
+
connect(S, Addr, Port, Opts) ->
connect(S, Addr, Port, Opts, infinity).
+-spec connect(Socket, Addr, Port, Opts, Timeout) ->
+ {ok, Assoc} | {error, posix()} when
+ Socket :: sctp_socket(),
+ Addr :: ip_address() | hostname(),
+ Port :: port_number(),
+ Opts :: [Opt :: sctp_option()],
+ Timeout :: timeout(),
+ Assoc :: #sctp_assoc_change{}.
+
connect(S, Addr, Port, Opts, Timeout) ->
case do_connect(S, Addr, Port, Opts, Timeout, true) of
badarg ->
@@ -88,9 +165,24 @@ connect(S, Addr, Port, Opts, Timeout) ->
Result
end.
+-spec connect_init(Socket, Addr, Port, Opts) ->
+ ok | {error, posix()} when
+ Socket :: sctp_socket(),
+ Addr :: ip_address() | hostname(),
+ Port :: port_number(),
+ Opts :: [sctp_option()].
+
connect_init(S, Addr, Port, Opts) ->
connect_init(S, Addr, Port, Opts, infinity).
+-spec connect_init(Socket, Addr, Port, Opts, Timeout) ->
+ ok | {error, posix()} when
+ Socket :: sctp_socket(),
+ Addr :: ip_address() | hostname(),
+ Port :: port_number(),
+ Opts :: [sctp_option()],
+ Timeout :: timeout().
+
connect_init(S, Addr, Port, Opts, Timeout) ->
case do_connect(S, Addr, Port, Opts, Timeout, false) of
badarg ->
@@ -130,12 +222,20 @@ do_connect(_S, _Addr, _Port, _Opts, _Timeout, _ConnWait) ->
badarg.
+-spec eof(Socket, Assoc) -> ok | {error, Reason} when
+ Socket :: sctp_socket(),
+ Assoc :: #sctp_assoc_change{},
+ Reason :: term().
eof(S, #sctp_assoc_change{assoc_id=AssocId}) when is_port(S) ->
eof_or_abort(S, AssocId, eof);
eof(S, Assoc) ->
erlang:error(badarg, [S,Assoc]).
+-spec abort(Socket, Assoc) -> ok | {error, posix()} when
+ Socket :: sctp_socket(),
+ Assoc :: #sctp_assoc_change{}.
+
abort(S, #sctp_assoc_change{assoc_id=AssocId}) when is_port(S) ->
eof_or_abort(S, AssocId, abort);
abort(S, Assoc) ->
@@ -151,6 +251,11 @@ eof_or_abort(S, AssocId, Action) ->
end.
+-spec send(Socket, SndRcvInfo, Data) -> ok | {error, Reason} when
+ Socket :: sctp_socket(),
+ SndRcvInfo :: #sctp_sndrcvinfo{},
+ Data :: binary | iolist(),
+ Reason :: term().
%% Full-featured send. Rarely needed.
send(S, #sctp_sndrcvinfo{}=SRI, Data) when is_port(S) ->
@@ -162,6 +267,13 @@ send(S, #sctp_sndrcvinfo{}=SRI, Data) when is_port(S) ->
send(S, SRI, Data) ->
erlang:error(badarg, [S,SRI,Data]).
+-spec send(Socket, Assoc, Stream, Data) -> ok | {error, Reason} when
+ Socket :: sctp_socket(),
+ Assoc :: #sctp_assoc_change{} | assoc_id(),
+ Stream :: integer(),
+ Data :: binary | iolist(),
+ Reason :: term().
+
send(S, #sctp_assoc_change{assoc_id=AssocId}, Stream, Data)
when is_port(S), is_integer(Stream) ->
case inet_db:lookup_socket(S) of
@@ -179,9 +291,36 @@ send(S, AssocId, Stream, Data)
send(S, AssocChange, Stream, Data) ->
erlang:error(badarg, [S,AssocChange,Stream,Data]).
+-spec recv(Socket) -> {ok, {FromIP, FromPort, AncData, Data}}
+ | {error, Reason} when
+ Socket :: sctp_socket(),
+ FromIP :: ip_address(),
+ FromPort :: port_number(),
+ AncData :: [#sctp_sndrcvinfo{}],
+ Data :: binary() | string() | #sctp_sndrcvinfo{}
+ | #sctp_assoc_change{} | #sctp_paddr_change{}
+ | #sctp_adaptation_event{},
+ Reason :: posix() | #sctp_send_failed{} | #sctp_paddr_change{}
+ | #sctp_pdapi_event{} | #sctp_remote_error{}
+ | #sctp_shutdown_event{}.
+
recv(S) ->
recv(S, infinity).
+-spec recv(Socket, Timeout) -> {ok, {FromIP, FromPort, AncData, Data}}
+ | {error, Reason} when
+ Socket :: sctp_socket(),
+ Timeout :: timeout(),
+ FromIP :: ip_address(),
+ FromPort :: port_number(),
+ AncData :: [#sctp_sndrcvinfo{}],
+ Data :: binary() | string() | #sctp_sndrcvinfo{}
+ | #sctp_assoc_change{} | #sctp_paddr_change{}
+ | #sctp_adaptation_event{},
+ Reason :: posix() | #sctp_send_failed{} | #sctp_paddr_change{}
+ | #sctp_pdapi_event{} | #sctp_remote_error{}
+ | #sctp_shutdown_event{}.
+
recv(S, Timeout) when is_port(S) ->
case inet_db:lookup_socket(S) of
{ok,Mod} ->
@@ -192,6 +331,8 @@ recv(S, Timeout) ->
erlang:error(badarg, [S,Timeout]).
+-spec error_string(ErrorNumber) -> ok | string() | unknown_error when
+ ErrorNumber :: integer().
error_string(0) ->
ok;
@@ -224,6 +365,9 @@ error_string(X) ->
erlang:error(badarg, [X]).
+-spec controlling_process(Socket, Pid) -> ok when
+ Socket :: sctp_socket(),
+ Pid :: pid().
controlling_process(S, Pid) when is_port(S), is_pid(Pid) ->
inet:udp_controlling_process(S, Pid);
diff --git a/lib/kernel/src/gen_tcp.erl b/lib/kernel/src/gen_tcp.erl
index 16a87d71b6..bee61ca84a 100644
--- a/lib/kernel/src/gen_tcp.erl
+++ b/lib/kernel/src/gen_tcp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -28,12 +28,35 @@
-include("inet_int.hrl").
+-type hostname() :: inet:hostname().
+-type ip_address() :: inet:ip_address().
+-type port_number() :: 0..65535.
+-type posix() :: inet:posix().
+-type socket() :: port().
+
%%
%% Connect a socket
%%
+
+-spec connect(Address, Port, Options) -> {ok, Socket} | {error, Reason} when
+ Address :: ip_address() | hostname(),
+ Port :: port_number(),
+ Options :: [Opt :: term()],
+ Socket :: socket(),
+ Reason :: posix().
+
connect(Address, Port, Opts) ->
connect(Address,Port,Opts,infinity).
+-spec connect(Address, Port, Options, Timeout) ->
+ {ok, Socket} | {error, Reason} when
+ Address :: ip_address() | hostname(),
+ Port :: port_number(),
+ Options :: [Opt :: term()],
+ Timeout :: timeout(),
+ Socket :: socket(),
+ Reason :: posix().
+
connect(Address, Port, Opts, Time) ->
Timer = inet:start_timer(Time),
Res = (catch connect1(Address,Port,Opts,Timer)),
@@ -72,6 +95,13 @@ try_connect([], _Port, _Opts, _Timer, _Mod, Err) ->
%%
%% Listen on a tcp port
%%
+
+-spec listen(Port, Options) -> {ok, ListenSocket} | {error, Reason} when
+ Port :: port_number(),
+ Options :: [Opt :: term()],
+ ListenSocket :: socket(),
+ Reason :: posix().
+
listen(Port, Opts) ->
Mod = mod(Opts, undefined),
case Mod:getserv(Port) of
@@ -85,6 +115,12 @@ listen(Port, Opts) ->
%%
%% Generic tcp accept
%%
+
+-spec accept(ListenSocket) -> {ok, Socket} | {error, Reason} when
+ ListenSocket :: socket(),
+ Socket :: socket(),
+ Reason :: closed | timeout | posix().
+
accept(S) ->
case inet_db:lookup_socket(S) of
{ok, Mod} ->
@@ -93,6 +129,12 @@ accept(S) ->
Error
end.
+-spec accept(ListenSocket, Timeout) -> {ok, Socket} | {error, Reason} when
+ ListenSocket :: socket(),
+ Timeout :: timeout(),
+ Socket :: socket(),
+ Reason :: closed | timeout | posix().
+
accept(S, Time) when is_port(S) ->
case inet_db:lookup_socket(S) of
{ok, Mod} ->
@@ -104,6 +146,12 @@ accept(S, Time) when is_port(S) ->
%%
%% Generic tcp shutdown
%%
+
+-spec shutdown(Socket, How) -> ok | {error, Reason} when
+ Socket :: socket(),
+ How :: read | write | read_write,
+ Reason :: posix().
+
shutdown(S, How) when is_port(S) ->
case inet_db:lookup_socket(S) of
{ok, Mod} ->
@@ -115,12 +163,22 @@ shutdown(S, How) when is_port(S) ->
%%
%% Close
%%
+
+-spec close(Socket) -> ok when
+ Socket :: socket().
+
close(S) ->
inet:tcp_close(S).
%%
%% Send
%%
+
+-spec send(Socket, Packet) -> ok | {error, Reason} when
+ Socket :: socket(),
+ Packet :: string() | binary(),
+ Reason :: posix().
+
send(S, Packet) when is_port(S) ->
case inet_db:lookup_socket(S) of
{ok, Mod} ->
@@ -132,6 +190,14 @@ send(S, Packet) when is_port(S) ->
%%
%% Receive data from a socket (passive mode)
%%
+
+-spec recv(Socket, Length) -> {ok, Packet} | {error, Reason} when
+ Socket :: socket(),
+ Length :: non_neg_integer(),
+ Packet :: string() | binary() | HttpPacket,
+ Reason :: closed | posix(),
+ HttpPacket :: term().
+
recv(S, Length) when is_port(S) ->
case inet_db:lookup_socket(S) of
{ok, Mod} ->
@@ -140,6 +206,14 @@ recv(S, Length) when is_port(S) ->
Error
end.
+-spec recv(Socket, Length, Timeout) -> {ok, Packet} | {error, Reason} when
+ Socket :: socket(),
+ Length :: non_neg_integer(),
+ Timeout :: timeout(),
+ Packet :: string() | binary() | HttpPacket,
+ Reason :: closed | posix(),
+ HttpPacket :: term().
+
recv(S, Length, Time) when is_port(S) ->
case inet_db:lookup_socket(S) of
{ok, Mod} ->
@@ -159,6 +233,12 @@ unrecv(S, Data) when is_port(S) ->
%%
%% Set controlling process
%%
+
+-spec controlling_process(Socket, Pid) -> ok | {error, Reason} when
+ Socket :: socket(),
+ Pid :: pid(),
+ Reason :: closed | not_owner | posix().
+
controlling_process(S, NewOwner) ->
case inet_db:lookup_socket(S) of
{ok, _Mod} -> % Just check that this is an open socket
diff --git a/lib/kernel/src/gen_udp.erl b/lib/kernel/src/gen_udp.erl
index 99020c7b6c..7d14615c04 100644
--- a/lib/kernel/src/gen_udp.erl
+++ b/lib/kernel/src/gen_udp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -25,17 +25,44 @@
-include("inet_int.hrl").
+-type hostname() :: inet:hostname().
+-type ip_address() :: inet:ip_address().
+-type port_number() :: 0..65535.
+-type posix() :: inet:posix().
+-type socket() :: port().
+
+-spec open(Port) -> {ok, Socket} | {error, Reason} when
+ Port :: port_number(),
+ Socket :: socket(),
+ Reason :: posix().
+
open(Port) ->
open(Port, []).
+-spec open(Port, Opts) -> {ok, Socket} | {error, Reason} when
+ Port :: port_number(),
+ Opts :: [Opt :: term()],
+ Socket :: socket(),
+ Reason :: posix().
+
open(Port, Opts) ->
Mod = mod(Opts, undefined),
{ok,UP} = Mod:getserv(Port),
Mod:open(UP, Opts).
+-spec close(Socket) -> ok when
+ Socket :: socket().
+
close(S) ->
inet:udp_close(S).
+-spec send(Socket, Address, Port, Packet) -> ok | {error, Reason} when
+ Socket :: socket(),
+ Address :: ip_address() | hostname(),
+ Port :: port_number(),
+ Packet :: string() | binary(),
+ Reason :: not_owner | posix().
+
send(S, Address, Port, Packet) when is_port(S) ->
case inet_db:lookup_socket(S) of
{ok, Mod} ->
@@ -61,6 +88,15 @@ send(S, Packet) when is_port(S) ->
Error
end.
+-spec recv(Socket, Length) ->
+ {ok, {Address, Port, Packet}} | {error, Reason} when
+ Socket :: socket(),
+ Length :: non_neg_integer(),
+ Address :: ip_address(),
+ Port :: port_number(),
+ Packet :: string() | binary(),
+ Reason :: not_owner | posix().
+
recv(S,Len) when is_port(S), is_integer(Len) ->
case inet_db:lookup_socket(S) of
{ok, Mod} ->
@@ -69,6 +105,16 @@ recv(S,Len) when is_port(S), is_integer(Len) ->
Error
end.
+-spec recv(Socket, Length, Timeout) ->
+ {ok, {Address, Port, Packet}} | {error, Reason} when
+ Socket :: socket(),
+ Length :: non_neg_integer(),
+ Timeout :: timeout(),
+ Address :: ip_address(),
+ Port :: port_number(),
+ Packet :: string() | binary(),
+ Reason :: not_owner | posix().
+
recv(S,Len,Time) when is_port(S) ->
case inet_db:lookup_socket(S) of
{ok, Mod} ->
@@ -90,6 +136,10 @@ connect(S, Address, Port) when is_port(S) ->
Error
end.
+-spec controlling_process(Socket, Pid) -> ok when
+ Socket :: socket(),
+ Pid :: pid().
+
controlling_process(S, NewOwner) ->
inet:udp_controlling_process(S, NewOwner).
diff --git a/lib/kernel/src/global.erl b/lib/kernel/src/global.erl
index 6343acd000..7d15f8bf83 100644
--- a/lib/kernel/src/global.erl
+++ b/lib/kernel/src/global.erl
@@ -166,7 +166,7 @@ start_link() ->
stop() ->
gen_server:call(global_name_server, stop, infinity).
--spec sync() -> 'ok' | {'error', term()}.
+-spec sync() -> 'ok' | {'error', Reason :: term()}.
sync() ->
case check_sync_nodes() of
{error, _} = Error ->
@@ -175,7 +175,7 @@ sync() ->
gen_server:call(global_name_server, {sync, SyncNodes}, infinity)
end.
--spec sync([node()]) -> 'ok' | {'error', term()}.
+-spec sync([node()]) -> 'ok' | {'error', Reason :: term()}.
sync(Nodes) ->
case check_sync_nodes(Nodes) of
{error, _} = Error ->
@@ -184,7 +184,10 @@ sync(Nodes) ->
gen_server:call(global_name_server, {sync, SyncNodes}, infinity)
end.
--spec send(term(), term()) -> pid().
+-spec send(Name, Msg) -> Pid when
+ Name :: term(),
+ Msg :: term(),
+ Pid :: pid().
send(Name, Msg) ->
case whereis_name(Name) of
Pid when is_pid(Pid) ->
@@ -195,7 +198,8 @@ send(Name, Msg) ->
end.
%% See OTP-3737.
--spec whereis_name(term()) -> pid() | 'undefined'.
+-spec whereis_name(Name) -> pid() | 'undefined' when
+ Name :: term().
whereis_name(Name) ->
where(Name).
@@ -219,13 +223,19 @@ node_disconnected(Node) ->
%% undefined which one of them is used.
%% Method blocks the name registration, but does not affect global locking.
%%-----------------------------------------------------------------
--spec register_name(term(), pid()) -> 'yes' | 'no'.
+-spec register_name(Name, Pid) -> 'yes' | 'no' when
+ Name :: term(),
+ Pid :: pid().
register_name(Name, Pid) when is_pid(Pid) ->
register_name(Name, Pid, fun random_exit_name/3).
--type method() :: fun((term(), pid(), pid()) -> pid() | 'none').
+-type method() :: fun((Name :: term(), Pid :: pid(), Pid2 :: pid()) ->
+ pid() | 'none').
--spec register_name(term(), pid(), method()) -> 'yes' | 'no'.
+-spec register_name(Name, Pid, Resolve) -> 'yes' | 'no' when
+ Name :: term(),
+ Pid :: pid(),
+ Resolve :: method().
register_name(Name, Pid, Method) when is_pid(Pid) ->
Fun = fun(Nodes) ->
case (where(Name) =:= undefined) andalso check_dupname(Name, Pid) of
@@ -257,7 +267,8 @@ check_dupname(Name, Pid) ->
end
end.
--spec unregister_name(term()) -> _.
+-spec unregister_name(Name) -> _ when
+ Name :: term().
unregister_name(Name) ->
case where(Name) of
undefined ->
@@ -273,11 +284,16 @@ unregister_name(Name) ->
gen_server:call(global_name_server, {registrar, Fun}, infinity)
end.
--spec re_register_name(term(), pid()) -> _.
+-spec re_register_name(Name, Pid) -> _ when
+ Name :: term(),
+ Pid :: pid().
re_register_name(Name, Pid) when is_pid(Pid) ->
re_register_name(Name, Pid, fun random_exit_name/3).
--spec re_register_name(term(), pid(), method()) -> _.
+-spec re_register_name(Name, Pid, Resolve) -> _ when
+ Name :: term(),
+ Pid :: pid(),
+ Resolve :: method().
re_register_name(Name, Pid, Method) when is_pid(Pid) ->
Fun = fun(Nodes) ->
gen_server:multi_call(Nodes,
@@ -288,7 +304,8 @@ re_register_name(Name, Pid, Method) when is_pid(Pid) ->
?trace({re_register_name, self(), Name, Pid, Method}),
gen_server:call(global_name_server, {registrar, Fun}, infinity).
--spec registered_names() -> [term()].
+-spec registered_names() -> [Name] when
+ Name :: term().
registered_names() ->
MS = ets:fun2ms(fun({Name,_Pid,_M,_RP,_R}) -> Name end),
ets:select(global_names, MS).
@@ -329,19 +346,25 @@ register_name_external(Name, Pid, Method) when is_pid(Pid) ->
unregister_name_external(Name) ->
unregister_name(Name).
--type id() :: {term(), term()}.
+-type id() :: {ResourceId :: term(), LockRequesterId :: term()}.
--spec set_lock(id()) -> boolean().
+-spec set_lock(Id) -> boolean() when
+ Id :: id().
set_lock(Id) ->
set_lock(Id, [node() | nodes()], infinity, 1).
-type retries() :: non_neg_integer() | 'infinity'.
--spec set_lock(id(), [node()]) -> boolean().
+-spec set_lock(Id, Nodes) -> boolean() when
+ Id :: id(),
+ Nodes :: [node()].
set_lock(Id, Nodes) ->
set_lock(Id, Nodes, infinity, 1).
--spec set_lock(id(), [node()], retries()) -> boolean().
+-spec set_lock(Id, Nodes, Retries) -> boolean() when
+ Id :: id(),
+ Nodes :: [node()],
+ Retries :: retries().
set_lock(Id, Nodes, Retries) when is_integer(Retries), Retries >= 0 ->
set_lock(Id, Nodes, Retries, 1);
set_lock(Id, Nodes, infinity) ->
@@ -363,11 +386,14 @@ set_lock({_ResourceId, _LockRequesterId} = Id, Nodes, Retries, Times) ->
set_lock(Id, Nodes, dec(Retries), Times+1)
end.
--spec del_lock(id()) -> 'true'.
+-spec del_lock(Id) -> 'true' when
+ Id :: id().
del_lock(Id) ->
del_lock(Id, [node() | nodes()]).
--spec del_lock(id(), [node()]) -> 'true'.
+-spec del_lock(Id, Nodes) -> 'true' when
+ Id :: id(),
+ Nodes :: [node()].
del_lock({_ResourceId, _LockRequesterId} = Id, Nodes) ->
?trace({del_lock, {me,self()}, Id, {nodes,Nodes}}),
gen_server:multi_call(Nodes, global_name_server, {del_lock, Id}),
@@ -375,13 +401,25 @@ del_lock({_ResourceId, _LockRequesterId} = Id, Nodes) ->
-type trans_fun() :: function() | {module(), atom()}.
--spec trans(id(), trans_fun()) -> term().
+-spec trans(Id, Fun) -> Res | aborted when
+ Id :: id(),
+ Fun :: trans_fun(),
+ Res :: term().
trans(Id, Fun) -> trans(Id, Fun, [node() | nodes()], infinity).
--spec trans(id(), trans_fun(), [node()]) -> term().
+-spec trans(Id, Fun, Nodes) -> Res | aborted when
+ Id :: id(),
+ Fun :: trans_fun(),
+ Nodes :: [node()],
+ Res :: term().
trans(Id, Fun, Nodes) -> trans(Id, Fun, Nodes, infinity).
--spec trans(id(), trans_fun(), [node()], retries()) -> term().
+-spec trans(Id, Fun, Nodes, Retries) -> Res | aborted when
+ Id :: id(),
+ Fun :: trans_fun(),
+ Nodes :: [node()],
+ Retries :: retries(),
+ Res :: term().
trans(Id, Fun, Nodes, Retries) ->
case set_lock(Id, Nodes, Retries) of
true ->
@@ -1928,7 +1966,10 @@ resolve_it(Method, Name, Pid1, Pid2) ->
minmax(P1,P2) ->
if node(P1) < node(P2) -> {P1, P2}; true -> {P2, P1} end.
--spec random_exit_name(term(), pid(), pid()) -> pid().
+-spec random_exit_name(Name, Pid1, Pid2) -> 'none' when
+ Name :: term(),
+ Pid1 :: pid(),
+ Pid2 :: pid().
random_exit_name(Name, Pid, Pid2) ->
{Min, Max} = minmax(Pid, Pid2),
error_logger:info_msg("global: Name conflict terminating ~w\n",
@@ -1936,12 +1977,19 @@ random_exit_name(Name, Pid, Pid2) ->
exit(Max, kill),
Min.
+-spec random_notify_name(Name, Pid1, Pid2) -> 'none' when
+ Name :: term(),
+ Pid1 :: pid(),
+ Pid2 :: pid().
random_notify_name(Name, Pid, Pid2) ->
{Min, Max} = minmax(Pid, Pid2),
Max ! {global_name_conflict, Name},
Min.
--spec notify_all_name(term(), pid(), pid()) -> 'none'.
+-spec notify_all_name(Name, Pid1, Pid2) -> 'none' when
+ Name :: term(),
+ Pid1 :: pid(),
+ Pid2 :: pid().
notify_all_name(Name, Pid, Pid2) ->
Pid ! {global_name_conflict, Name, Pid2},
Pid2 ! {global_name_conflict, Name, Pid},
diff --git a/lib/kernel/src/global_group.erl b/lib/kernel/src/global_group.erl
index 7e141ac5c7..025a9b8a5b 100644
--- a/lib/kernel/src/global_group.erl
+++ b/lib/kernel/src/global_group.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -62,9 +62,10 @@
-type sync_state() :: 'no_conf' | 'synced'.
-type group_name() :: atom().
--type group_tuple() :: {group_name(), [node()]}
- | {group_name(), publish_type(), [node()]}.
-
+-type group_tuple() :: {GroupName :: group_name(), [node()]}
+ | {GroupName :: group_name(),
+ PublishType :: publish_type(),
+ [node()]}.
%%%====================================================================================
%%% The state of the global_group process
@@ -97,11 +98,14 @@
%%% External exported
%%%====================================================================================
--spec global_groups() -> {group_name(), [group_name()]} | 'undefined'.
+-spec global_groups() -> {GroupName, GroupNames} | undefined when
+ GroupName :: group_name(),
+ GroupNames :: [GroupName].
global_groups() ->
request(global_groups).
--spec monitor_nodes(boolean()) -> 'ok'.
+-spec monitor_nodes(Flag) -> 'ok' when
+ Flag :: boolean().
monitor_nodes(Flag) ->
case Flag of
true -> request({monitor_nodes, Flag});
@@ -109,30 +113,41 @@ monitor_nodes(Flag) ->
_ -> {error, not_boolean}
end.
--spec own_nodes() -> [node()].
+-spec own_nodes() -> Nodes when
+ Nodes :: [Node :: node()].
own_nodes() ->
request(own_nodes).
-type name() :: atom().
-type where() :: {'node', node()} | {'group', group_name()}.
--spec registered_names(where()) -> [name()].
+-spec registered_names(Where) -> Names when
+ Where :: where(),
+ Names :: [Name :: name()].
registered_names(Arg) ->
request({registered_names, Arg}).
--spec send(name(), term()) -> pid() | {'badarg', {name(), term()}}.
+-spec send(Name, Msg) -> pid() | {'badarg', {Name, Msg}} when
+ Name :: name(),
+ Msg :: term().
send(Name, Msg) ->
request({send, Name, Msg}).
--spec send(where(), name(), term()) -> pid() | {'badarg', {name(), term()}}.
+-spec send(Where, Name, Msg) -> pid() | {'badarg', {Name, Msg}} when
+ Where :: where(),
+ Name :: name(),
+ Msg :: term().
send(Group, Name, Msg) ->
request({send, Group, Name, Msg}).
--spec whereis_name(name()) -> pid() | 'undefined'.
+-spec whereis_name(Name) -> pid() | 'undefined' when
+ Name :: name().
whereis_name(Name) ->
request({whereis_name, Name}).
--spec whereis_name(where(), name()) -> pid() | 'undefined'.
+-spec whereis_name(Where, Name) -> pid() | 'undefined' when
+ Where :: where(),
+ Name :: name().
whereis_name(Group, Name) ->
request({whereis_name, Group, Name}).
@@ -155,14 +170,14 @@ ng_add_check(Node, OthersNG) ->
ng_add_check(Node, PubType, OthersNG) ->
request({ng_add_check, Node, PubType, OthersNG}).
--type info_item() :: {'state', sync_state()}
- | {'own_group_name', group_name()}
- | {'own_group_nodes', [node()]}
- | {'synched_nodes', [node()]}
- | {'sync_error', [node()]}
- | {'no_contact', [node()]}
- | {'other_groups', [group_tuple()]}
- | {'monitoring', [pid()]}.
+-type info_item() :: {'state', State :: sync_state()}
+ | {'own_group_name', GroupName :: group_name()}
+ | {'own_group_nodes', Nodes :: [node()]}
+ | {'synched_nodes', Nodes :: [node()]}
+ | {'sync_error', Nodes :: [node()]}
+ | {'no_contact', Nodes :: [node()]}
+ | {'other_groups', Groups :: [group_tuple()]}
+ | {'monitoring', Pids :: [pid()]}.
-spec info() -> [info_item()].
info() ->
@@ -1012,6 +1027,7 @@ grp_tuple({Name, normal, Nodes}) ->
%%% The special process which checks that all nodes in the own global group
%%% agrees on the configuration.
%%%====================================================================================
+-spec sync_init(_, _, _, _) -> no_return().
sync_init(Type, Cname, PubType, Nodes) ->
{Up, Down} = sync_check_node(lists:delete(node(), Nodes), [], []),
sync_check_init(Type, Up, Cname, Nodes, Down, PubType).
@@ -1032,9 +1048,11 @@ sync_check_node([Node|Nodes], Up, Down) ->
%%% Check that all nodes are in agreement of the global
%%% group configuration.
%%%-------------------------------------------------------------
+-spec sync_check_init(_, _, _, _, _, _) -> no_return().
sync_check_init(Type, Up, Cname, Nodes, Down, PubType) ->
sync_check_init(Type, Up, Cname, Nodes, 3, [], Down, PubType).
+-spec sync_check_init(_, _, _, _, _, _, _, _) -> no_return().
sync_check_init(_Type, NoContact, _Cname, _Nodes, 0, ErrorNodes, Down, _PubType) ->
case ErrorNodes of
[] ->
diff --git a/lib/kernel/src/global_search.erl b/lib/kernel/src/global_search.erl
index b723e18a1b..0bf53e29b8 100644
--- a/lib/kernel/src/global_search.erl
+++ b/lib/kernel/src/global_search.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -69,6 +69,7 @@ start(Flag, Arg) ->
%%%====================================================================================
%%%====================================================================================
+-spec init_send(_) -> no_return().
init_send({any, NodesList, Name, Msg, From}) ->
case whereis_any_loop(NodesList, Name) of
undefined ->
@@ -115,6 +116,7 @@ init_send({node, Node, Name, Msg, From}) ->
%%%====================================================================================
%%%====================================================================================
+-spec init_whereis(_) -> no_return().
init_whereis({any, NodesList, Name, From}) ->
R = whereis_any_loop(NodesList, Name),
gen_server:cast(global_group, {find_name_res, R, self(), From}),
@@ -146,6 +148,7 @@ init_whereis({node, Node, Name, From}) ->
%%%====================================================================================
%%%====================================================================================
%%%====================================================================================
+-spec init_names(_) -> no_return().
init_names({group, Nodes, From}) ->
case names_group_loop(Nodes) of
group_down ->
diff --git a/lib/kernel/src/heart.erl b/lib/kernel/src/heart.erl
index e78acfc7a6..255ae4e51b 100644
--- a/lib/kernel/src/heart.erl
+++ b/lib/kernel/src/heart.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -85,19 +85,21 @@ init(Starter, Parent) ->
Starter ! {start_error, self()}
end.
--spec set_cmd(string()) -> 'ok' | {'error', {'bad_cmd', string()}}.
+-spec set_cmd(Cmd) -> 'ok' | {'error', {'bad_cmd', Cmd}} when
+ Cmd :: string().
set_cmd(Cmd) ->
heart ! {self(), set_cmd, Cmd},
wait().
--spec get_cmd() -> 'ok'.
+-spec get_cmd() -> {ok, Cmd} when
+ Cmd :: string().
get_cmd() ->
heart ! {self(), get_cmd},
wait().
--spec clear_cmd() -> {'ok', string()}.
+-spec clear_cmd() -> ok.
clear_cmd() ->
heart ! {self(), clear_cmd},
diff --git a/lib/kernel/src/inet.erl b/lib/kernel/src/inet.erl
index 327e0f93f1..5649188c38 100644
--- a/lib/kernel/src/inet.erl
+++ b/lib/kernel/src/inet.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -63,7 +63,8 @@
%% timer interface
-export([start_timer/1, timeout/1, timeout/2, stop_timer/1]).
--export_type([ip_address/0, socket/0]).
+-export_type([family_option/0, hostent/0, hostname/0, ip4_address/0,
+ ip6_address/0, ip_address/0, posix/0, socket/0]).
%% imports
-import(lists, [append/1, duplicate/2, filter/2, foldl/3]).
@@ -79,8 +80,16 @@
%%% ---------------------------------
%%% Contract type definitions
+
+-type hostent() :: #hostent{}.
+-type hostname() :: atom() | string().
+-type ip4_address() :: {0..255,0..255,0..255,0..255}.
+-type ip6_address() :: {0..65535,0..65535,0..65535,0..65535,
+ 0..65535,0..65535,0..65535,0..65535}.
+-type ip_address() :: ip4_address() | ip6_address().
+-type ip_port() :: 0..65535.
+-type posix() :: exbadport | exbadseq | file:posix().
-type socket() :: port().
--type posix() :: atom().
-type socket_setopt() ::
{'raw', non_neg_integer(), non_neg_integer(), binary()} |
@@ -106,7 +115,7 @@
{'packet',
0 | 1 | 2 | 4 | 'raw' | 'sunrm' | 'asn1' |
'cdr' | 'fcgi' | 'line' | 'tpkt' | 'http' | 'httph' | 'http_bin' | 'httph_bin' } |
- {'mode', list() | binary()} |
+ {'mode', 'list' | 'binary'} |
{'port', 'port', 'term'} |
{'exit_on_close', boolean()} |
{'low_watermark', non_neg_integer()} |
@@ -195,12 +204,13 @@
%%% ---------------------------------
--spec get_rc() -> [{any(),any()}].
+-spec get_rc() -> [{Par :: any(), Val :: any()}].
get_rc() ->
inet_db:get_rc().
--spec close(Socket :: socket()) -> 'ok'.
+-spec close(Socket) -> 'ok' when
+ Socket :: socket().
close(Socket) ->
prim_inet:close(Socket),
@@ -211,8 +221,10 @@ close(Socket) ->
ok
end.
--spec peername(Socket :: socket()) ->
- {'ok', {ip_address(), non_neg_integer()}} | {'error', posix()}.
+-spec peername(Socket) -> {ok, {Address, Port}} | {error, posix()} when
+ Socket :: socket(),
+ Address :: ip_address(),
+ Port :: non_neg_integer().
peername(Socket) ->
prim_inet:peername(Socket).
@@ -226,8 +238,10 @@ setpeername(Socket, undefined) ->
prim_inet:setpeername(Socket, undefined).
--spec sockname(Socket :: socket()) ->
- {'ok', {ip_address(), non_neg_integer()}} | {'error', posix()}.
+-spec sockname(Socket) -> {ok, {Address, Port}} | {error, posix()} when
+ Socket :: socket(),
+ Address :: ip_address(),
+ Port :: non_neg_integer().
sockname(Socket) ->
prim_inet:sockname(Socket).
@@ -260,8 +274,10 @@ send(Socket, Packet) ->
setopts(Socket, Opts) ->
prim_inet:setopts(Socket, Opts).
--spec getopts(Socket :: socket(), Opts :: [socket_getopt()]) ->
- {'ok', [socket_setopt()]} | {'error', posix()}.
+-spec getopts(Socket, Options) ->
+ {'ok', [socket_setopt()]} | {'error', posix()} when
+ Socket :: socket(),
+ Options :: [socket_getopt()].
getopts(Socket, Opts) ->
prim_inet:getopts(Socket, Opts).
@@ -272,7 +288,19 @@ getopts(Socket, Opts) ->
getifaddrs(Socket) ->
prim_inet:getifaddrs(Socket).
--spec getifaddrs() -> {'ok', [string()]} | {'error', posix()}.
+-spec getifaddrs() -> {ok, Iflist} | {error, posix()} when
+ Iflist :: [{Ifname,[Ifopt]}],
+ Ifname :: string(),
+ Ifopt :: {flag,[Flag]} | {addr,Addr} | {netmask,Netmask}
+ | {broadaddr,Broadaddr} | {dstaddr,Dstaddr}
+ | {hwaddr,Hwaddr},
+ Flag :: up | broadcast | loopback | pointtopoint
+ | running | multicast,
+ Addr :: ip_address(),
+ Netmask :: ip_address(),
+ Broadaddr :: ip_address(),
+ Dstaddr :: ip_address(),
+ Hwaddr :: [byte()].
getifaddrs() ->
withsocket(fun(S) -> prim_inet:getifaddrs(S) end).
@@ -371,7 +399,8 @@ popf(_Socket) ->
% use of the DHCP-protocol
% should never fail
--spec gethostname() -> {'ok', string()}.
+-spec gethostname() -> {'ok', Hostname} when
+ Hostname :: string().
gethostname() ->
case inet_udp:open(0,[]) of
@@ -402,19 +431,23 @@ getstat(Socket) ->
getstat(Socket,What) ->
prim_inet:getstat(Socket, What).
--spec gethostbyname(Name :: string() | atom()) ->
- {'ok', #hostent{}} | {'error', posix()}.
+-spec gethostbyname(Hostname) -> {ok, Hostent} | {error, posix()} when
+ Hostname :: hostname(),
+ Hostent :: hostent().
gethostbyname(Name) ->
gethostbyname_tm(Name, inet, false).
--spec gethostbyname(Name :: string() | atom(), Family :: family_option()) ->
- {'ok', #hostent{}} | {'error', posix()}.
+-spec gethostbyname(Hostname, Family) ->
+ {ok, Hostent} | {error, posix()} when
+ Hostname :: hostname(),
+ Family :: family_option(),
+ Hostent :: hostent().
gethostbyname(Name,Family) ->
gethostbyname_tm(Name, Family, false).
--spec gethostbyname(Name :: string() | atom(),
+-spec gethostbyname(Name :: hostname(),
Family :: family_option(),
Timeout :: non_neg_integer() | 'infinity') ->
{'ok', #hostent{}} | {'error', posix()}.
@@ -439,8 +472,9 @@ gethostbyname_tm(Name,Family,Timer) ->
gethostbyname_tm(Name, Family, Timer, Opts).
--spec gethostbyaddr(Address :: string() | ip_address()) ->
- {'ok', #hostent{}} | {'error', posix()}.
+-spec gethostbyaddr(Address) -> {ok, Hostent} | {error, posix()} when
+ Address :: string() | ip_address(),
+ Hostent :: hostent().
gethostbyaddr(Address) ->
gethostbyaddr_tm(Address, false).
@@ -491,14 +525,15 @@ getfd(Socket) ->
%% Lookup an ip address
%%
--spec getaddr(Host :: ip_address() | string() | atom(),
- Family :: family_option()) ->
- {'ok', ip_address()} | {'error', posix()}.
+-spec getaddr(Host, Family) -> {ok, Address} | {error, posix()} when
+ Host :: ip_address() | hostname(),
+ Family :: family_option(),
+ Address :: ip_address().
getaddr(Address, Family) ->
getaddr(Address, Family, infinity).
--spec getaddr(Host :: ip_address() | string() | atom(),
+-spec getaddr(Host :: ip_address() | hostname(),
Family :: family_option(),
Timeout :: non_neg_integer() | 'infinity') ->
{'ok', ip_address()} | {'error', posix()}.
@@ -515,9 +550,11 @@ getaddr_tm(Address, Family, Timer) ->
Error -> Error
end.
--spec getaddrs(Host :: ip_address() | string() | atom(),
- Family :: family_option()) ->
- {'ok', [ip_address()]} | {'error', posix()}.
+-spec getaddrs(Host, Family) ->
+ {ok, Addresses} | {error, posix()} when
+ Host :: ip_address() | hostname(),
+ Family :: family_option(),
+ Addresses :: [ip_address()].
getaddrs(Address, Family) ->
getaddrs(Address, Family, infinity).
@@ -1237,7 +1274,8 @@ port_list(Name) ->
%% utils
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--spec format_error(posix()) -> string().
+-spec format_error(Posix) -> string() when
+ Posix :: posix().
format_error(exbadport) -> "invalid port state";
format_error(exbadseq) -> "bad command sequence";
diff --git a/lib/kernel/src/inet_res.erl b/lib/kernel/src/inet_res.erl
index 93563c6011..d5a8a2f134 100644
--- a/lib/kernel/src/inet_res.erl
+++ b/lib/kernel/src/inet_res.erl
@@ -47,18 +47,93 @@
false -> ok
end).
+-type res_option() ::
+ {alt_nameservers, [nameserver()]}
+ | {edns, 0 | false}
+ | {inet6, boolean()}
+ | {nameservers, [nameserver()]}
+ | {recurse, boolean()}
+ | {retry, integer()}
+ | {timeout, integer()}
+ | {udp_payload_size, integer()}
+ | {usevc, boolean()}.
+
+-type nameserver() :: {inet:ip_address(), Port :: 1..65535}.
+
+-type res_error() :: formerr | qfmterror | servfail | nxdomain |
+ notimp | refused | badvers | timeout.
+
+-type dns_name() :: string().
+
+-type rr_type() :: a | aaaa | cname | gid | hinfo | ns | mb | md | mg | mf
+ | minfo | mx | naptr | null | ptr | soa | spf | srv | txt
+ | uid | uinfo | unspec | wks.
+
+-type dns_class() :: in | chaos | hs | any.
+
+-opaque dns_msg() :: term().
+
+-type dns_data() ::
+ dns_name()
+ | inet:ip4_address()
+ | inet:ip6_address()
+ | {MName :: dns_name(),
+ RName :: dns_name(),
+ Serial :: integer(),
+ Refresh :: integer(),
+ Retry :: integer(),
+ Expiry :: integer(),
+ Minimum :: integer()}
+ | {inet:ip4_address(), Proto :: integer(), BitMap :: binary()}
+ | {CpuString :: string(), OsString :: string()}
+ | {RM :: dns_name(), EM :: dns_name()}
+ | {Prio :: integer(), dns_name()}
+ | {Prio :: integer(),Weight :: integer(),Port :: integer(),dns_name()}
+ | {Order :: integer(),Preference :: integer(),Flags :: string(),
+ Services :: string(),Regexp :: string(), dns_name()}
+ | [string()]
+ | binary().
+
%% --------------------------------------------------------------------------
%% resolve:
%%
%% Nameserver query
%%
+-spec resolve(Name, Class, Type) -> {ok, dns_msg()} | Error when
+ Name :: dns_name() | inet:ip_address(),
+ Class :: dns_class(),
+ Type :: rr_type(),
+ Error :: {error, Reason} | {error,{Reason,dns_msg()}},
+ Reason :: inet:posix() | res_error().
+
resolve(Name, Class, Type) ->
resolve(Name, Class, Type, [], infinity).
+-spec resolve(Name, Class, Type, Opts) ->
+ {ok, dns_msg()} | Error when
+ Name :: dns_name() | inet:ip_address(),
+ Class :: dns_class(),
+ Type :: rr_type(),
+ Opts :: [Opt],
+ Opt :: res_option() | verbose | atom(),
+ Error :: {error, Reason} | {error,{Reason,dns_msg()}},
+ Reason :: inet:posix() | res_error().
+
resolve(Name, Class, Type, Opts) ->
resolve(Name, Class, Type, Opts, infinity).
+-spec resolve(Name, Class, Type, Opts, Timeout) ->
+ {ok, dns_msg()} | Error when
+ Name :: dns_name() | inet:ip_address(),
+ Class :: dns_class(),
+ Type :: rr_type(),
+ Opts :: [Opt],
+ Opt :: res_option() | verbose | atom(),
+ Timeout :: timeout(),
+ Error :: {error, Reason} | {error,{Reason,dns_msg()}},
+ Reason :: inet:posix() | res_error().
+
resolve(Name, Class, Type, Opts, Timeout) ->
case nsdname(Name) of
{ok, Nm} ->
@@ -76,12 +151,30 @@ resolve(Name, Class, Type, Opts, Timeout) ->
%% Convenience wrapper to resolve/3,4,5 that filters out all answer data
%% fields of the class and type asked for.
+-spec lookup(Name, Class, Type) -> [dns_data()] when
+ Name :: dns_name() | inet:ip_address(),
+ Class :: dns_class(),
+ Type :: rr_type().
+
lookup(Name, Class, Type) ->
lookup(Name, Class, Type, []).
+-spec lookup(Name, Class, Type, Opts) -> [dns_data()] when
+ Name :: dns_name() | inet:ip_address(),
+ Class :: dns_class(),
+ Type :: rr_type(),
+ Opts :: [res_option() | verbose].
+
lookup(Name, Class, Type, Opts) ->
lookup(Name, Class, Type, Opts, infinity).
+-spec lookup(Name, Class, Type, Opts, Timeout) -> [dns_data()] when
+ Name :: dns_name() | inet:ip_address(),
+ Class :: dns_class(),
+ Type :: rr_type(),
+ Opts :: [res_option() | verbose],
+ Timeout :: timeout().
+
lookup(Name, Class, Type, Opts, Timeout) ->
lookup_filter(resolve(Name, Class, Type, Opts, Timeout),
Class, Type).
@@ -101,17 +194,55 @@ lookup_filter({error,_}, _, _) -> [].
%%
%% To be deprecated
+-spec nslookup(Name, Class, Type) -> {ok, dns_msg()} | {error, Reason} when
+ Name :: dns_name() | inet:ip_address(),
+ Class :: dns_class(),
+ Type :: rr_type(),
+ Reason :: inet:posix() | res_error().
+
nslookup(Name, Class, Type) ->
do_nslookup(Name, Class, Type, [], infinity).
+-spec nslookup(Name, Class, Type, Timeout) ->
+ {ok, dns_msg()} | {error, Reason} when
+ Name :: dns_name() | inet:ip_address(),
+ Class :: dns_class(),
+ Type :: rr_type(),
+ Timeout :: timeout(),
+ Reason :: inet:posix() | res_error();
+ (Name, Class, Type, Nameservers) ->
+ {ok, dns_msg()} | {error, Reason} when
+ Name :: dns_name() | inet:ip_address(),
+ Class :: dns_class(),
+ Type :: rr_type(),
+ Nameservers :: [nameserver()],
+ Reason :: inet:posix() | res_error().
+
nslookup(Name, Class, Type, Timeout) when is_integer(Timeout), Timeout >= 0 ->
do_nslookup(Name, Class, Type, [], Timeout);
nslookup(Name, Class, Type, NSs) -> % For backwards compatibility
nnslookup(Name, Class, Type, NSs). % with OTP R6B only
+-spec nnslookup(Name, Class, Type, Nameservers) ->
+ {ok, dns_msg()} | {error, Reason} when
+ Name :: dns_name() | inet:ip_address(),
+ Class :: dns_class(),
+ Type :: rr_type(),
+ Nameservers :: [nameserver()],
+ Reason :: inet:posix().
+
nnslookup(Name, Class, Type, NSs) ->
nnslookup(Name, Class, Type, NSs, infinity).
+-spec nnslookup(Name, Class, Type, Nameservers, Timeout) ->
+ {ok, dns_msg()} | {error, Reason} when
+ Name :: dns_name() | inet:ip_address(),
+ Class :: dns_class(),
+ Type :: rr_type(),
+ Timeout :: timeout(),
+ Nameservers :: [nameserver()],
+ Reason :: inet:posix().
+
nnslookup(Name, Class, Type, NSs, Timeout) ->
do_nslookup(Name, Class, Type, [{nameservers,NSs}], Timeout).
@@ -192,8 +323,19 @@ make_options(Opts, [Name|Names]) ->
%%
%% --------------------------------------------------------------------------
+-spec gethostbyaddr(Address) -> {ok, Hostent} | {error, Reason} when
+ Address :: inet:ip_address(),
+ Hostent :: inet:hostent(),
+ Reason :: inet:posix() | res_error().
+
gethostbyaddr(IP) -> gethostbyaddr_tm(IP,false).
+-spec gethostbyaddr(Address, Timeout) -> {ok, Hostent} | {error, Reason} when
+ Address :: inet:ip_address(),
+ Timeout :: timeout(),
+ Hostent :: inet:hostent(),
+ Reason :: inet:posix() | res_error().
+
gethostbyaddr(IP,Timeout) ->
Timer = inet:start_timer(Timeout),
Res = gethostbyaddr_tm(IP,Timer),
@@ -249,6 +391,11 @@ res_gethostbyaddr(Addr, IP, Timer) ->
%% Caches the answer.
%% --------------------------------------------------------------------------
+-spec gethostbyname(Name) -> {ok, Hostent} | {error, Reason} when
+ Name :: dns_name(),
+ Hostent :: inet:hostent(),
+ Reason :: inet:posix() | res_error().
+
gethostbyname(Name) ->
case inet_db:res_option(inet6) of
true ->
@@ -257,9 +404,23 @@ gethostbyname(Name) ->
gethostbyname_tm(Name, inet, false)
end.
+-spec gethostbyname(Name, Family) -> {ok, Hostent} | {error, Reason} when
+ Name :: dns_name(),
+ Hostent :: inet:hostent(),
+ Family :: inet:family_option(),
+ Reason :: inet:posix() | res_error().
+
gethostbyname(Name,Family) ->
gethostbyname_tm(Name,Family,false).
+-spec gethostbyname(Name, Family, Timeout) ->
+ {ok, Hostent} | {error, Reason} when
+ Name :: dns_name(),
+ Hostent :: inet:hostent(),
+ Timeout :: timeout(),
+ Family :: inet:family_option(),
+ Reason :: inet:posix() | res_error().
+
gethostbyname(Name,Family,Timeout) ->
Timer = inet:start_timer(Timeout),
Res = gethostbyname_tm(Name,Family,Timer),
@@ -298,14 +459,27 @@ gethostbyname_tm(_Name, _Family, _Timer) ->
%%
%% getbyname(domain_name(), Type) => {ok, hostent()} | {error, Reason}
%%
-%% where domain_name() is domain string or atom and Type is ?S_A, ?S_MX ...
+%% where domain_name() is domain string and Type is ?S_A, ?S_MX ...
%%
%% Caches the answer.
%% --------------------------------------------------------------------------
+-spec getbyname(Name, Type) -> {ok, Hostent} | {error, Reason} when
+ Name :: dns_name(),
+ Type :: rr_type(),
+ Hostent :: inet:hostent(),
+ Reason :: inet:posix() | res_error().
+
getbyname(Name, Type) ->
getbyname_tm(Name,Type,false).
+-spec getbyname(Name, Type, Timeout) -> {ok, Hostent} | {error, Reason} when
+ Name :: dns_name(),
+ Type :: rr_type(),
+ Timeout :: timeout(),
+ Hostent :: inet:hostent(),
+ Reason :: inet:posix() | res_error().
+
getbyname(Name, Type, Timeout) ->
Timer = inet:start_timer(Timeout),
Res = getbyname_tm(Name, Type, Timer),
diff --git a/lib/kernel/src/inet_udp.erl b/lib/kernel/src/inet_udp.erl
index 9a4089ab19..60bd96f332 100644
--- a/lib/kernel/src/inet_udp.erl
+++ b/lib/kernel/src/inet_udp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -39,8 +39,10 @@ getserv(Name) when is_atom(Name) -> inet:getservbyname(Name,udp).
getaddr(Address) -> inet:getaddr(Address, inet).
getaddr(Address,Timer) -> inet:getaddr_tm(Address, inet, Timer).
+-spec open(_) -> {ok, inet:socket()} | {error, atom()}.
open(Port) -> open(Port, []).
+-spec open(_, _) -> {ok, inet:socket()} | {error, atom()}.
open(Port, Opts) ->
case inet:udp_options(
[{port,Port}, {recbuf, ?RECBUF} | Opts],
@@ -69,6 +71,8 @@ recv(S,Len) ->
recv(S,Len,Time) ->
prim_inet:recvfrom(S, Len, Time).
+-spec close(inet:socket()) -> ok.
+
close(S) ->
inet:udp_close(S).
diff --git a/lib/kernel/src/net_adm.erl b/lib/kernel/src/net_adm.erl
index 737b1ecee9..9b2dac9544 100644
--- a/lib/kernel/src/net_adm.erl
+++ b/lib/kernel/src/net_adm.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -35,7 +35,11 @@
%% Try to read .hosts.erlang file in
%% 1. cwd , 2. $HOME 3. init:root_dir()
--spec host_file() -> [atom()] | {'error',atom() | {integer(),atom(),_}}.
+-spec host_file() -> Hosts | {error, Reason} when
+ Hosts :: [Host :: atom()],
+ %% Copied from file:path_consult/2:
+ Reason :: file:posix() | badarg | terminated | system_limit
+ | {Line :: integer(), Mod :: module(), Term :: term()}.
host_file() ->
Home = case init:get_argument(home) of
@@ -50,7 +54,8 @@ host_file() ->
%% Check whether a node is up or down
%% side effect: set up a connection to Node if there not yet is one.
--spec ping(atom()) -> 'pang' | 'pong'.
+-spec ping(Node) -> pong | pang when
+ Node :: atom().
ping(Node) when is_atom(Node) ->
case catch gen:call({net_kernel, Node},
@@ -63,7 +68,8 @@ ping(Node) when is_atom(Node) ->
pang
end.
--spec localhost() -> string().
+-spec localhost() -> Name when
+ Name :: string().
localhost() ->
{ok, Host} = inet:gethostname(),
@@ -73,12 +79,20 @@ localhost() ->
end.
--spec names() -> {'ok', [{string(), integer()}]} | {'error', _}.
+-spec names() -> {ok, [{Name, Port}]} | {error, Reason} when
+ Name :: string(),
+ Port :: non_neg_integer(),
+ Reason :: address | file:posix().
names() ->
names(localhost()).
--spec names(atom() | string()) -> {'ok', [{string(), integer()}]} | {'error', _}.
+
+-spec names(Host) -> {ok, [{Name, Port}]} | {error, Reason} when
+ Host :: atom() | string(),
+ Name :: string(),
+ Port :: non_neg_integer(),
+ Reason :: address | file:posix().
names(Hostname) ->
case inet:gethostbyname(Hostname) of
@@ -88,8 +102,9 @@ names(Hostname) ->
Else
end.
--spec dns_hostname(atom() | string()) ->
- {'ok', string()} | {'error', atom() | string()}.
+-spec dns_hostname(Host) -> {ok, Name} | {error, Host} when
+ Host :: atom() | string(),
+ Name :: string().
dns_hostname(Hostname) ->
case inet:gethostbyname(Hostname) of
@@ -164,7 +179,8 @@ collect_new(Sofar, Nodelist) ->
world() ->
world(silent).
--spec world(verbosity()) -> [node()].
+-spec world(Arg) -> [node()] when
+ Arg :: verbosity().
world(Verbose) ->
case net_adm:host_file() of
@@ -172,12 +188,15 @@ world(Verbose) ->
Hosts -> expand_hosts(Hosts, Verbose)
end.
--spec world_list([atom()]) -> [node()].
+-spec world_list(Hosts) -> [node()] when
+ Hosts :: [atom()].
world_list(Hosts) when is_list(Hosts) ->
expand_hosts(Hosts, silent).
--spec world_list([atom()], verbosity()) -> [node()].
+-spec world_list(Hosts, Arg) -> [node()] when
+ Hosts :: [atom()],
+ Arg :: verbosity().
world_list(Hosts, Verbose) when is_list(Hosts) ->
expand_hosts(Hosts, Verbose).
diff --git a/lib/kernel/src/net_kernel.erl b/lib/kernel/src/net_kernel.erl
index 5228d4fe01..9e3d730cee 100644
--- a/lib/kernel/src/net_kernel.erl
+++ b/lib/kernel/src/net_kernel.erl
@@ -145,8 +145,15 @@
%% Interface functions
kernel_apply(M,F,A) -> request({apply,M,F,A}).
+
+-spec allow(Nodes) -> ok | error when
+ Nodes :: [node()].
allow(Nodes) -> request({allow, Nodes}).
+
longnames() -> request(longnames).
+
+-spec stop() -> ok | {error, Reason} when
+ Reason :: not_allowed | not_found.
stop() -> erl_distribution:stop().
node_info(Node) -> get_node_info(Node).
@@ -158,10 +165,28 @@ i(Node) -> print_info(Node).
verbose(Level) when is_integer(Level) ->
request({verbose, Level}).
+-spec set_net_ticktime(NetTicktime, TransitionPeriod) -> Res when
+ NetTicktime :: pos_integer(),
+ TransitionPeriod :: non_neg_integer(),
+ Res :: unchanged
+ | change_initiated
+ | {ongoing_change_to, NewNetTicktime},
+ NewNetTicktime :: pos_integer().
set_net_ticktime(T, TP) when is_integer(T), T > 0, is_integer(TP), TP >= 0 ->
ticktime_res(request({new_ticktime, T*250, TP*1000})).
+
+-spec set_net_ticktime(NetTicktime) -> Res when
+ NetTicktime :: pos_integer(),
+ Res :: unchanged
+ | change_initiated
+ | {ongoing_change_to, NewNetTicktime},
+ NewNetTicktime :: pos_integer().
set_net_ticktime(T) when is_integer(T) ->
set_net_ticktime(T, ?DEFAULT_TRANSITION_PERIOD).
+
+-spec get_net_ticktime() -> Res when
+ Res :: NetTicktime | {ongoing_change_to, NetTicktime} | ignored,
+ NetTicktime :: pos_integer().
get_net_ticktime() ->
ticktime_res(request(ticktime)).
@@ -171,6 +196,9 @@ get_net_ticktime() ->
%% flags (we may want to move it elsewhere later). In order to easily
%% be backward compatible, errors are created here when process_flag()
%% fails.
+-spec monitor_nodes(Flag) -> ok | Error when
+ Flag :: boolean(),
+ Error :: error | {error, term()}.
monitor_nodes(Flag) ->
case catch process_flag(monitor_nodes, Flag) of
true -> ok;
@@ -178,6 +206,13 @@ monitor_nodes(Flag) ->
_ -> mk_monitor_nodes_error(Flag, [])
end.
+-spec monitor_nodes(Flag, Options) -> ok | Error when
+ Flag :: boolean(),
+ Options :: [Option],
+ Option :: {node_type, NodeType}
+ | nodedown_reason,
+ NodeType :: visible | hidden | all,
+ Error :: error | {error, term()}.
monitor_nodes(Flag, Opts) ->
case catch process_flag({monitor_nodes, Opts}, Flag) of
true -> ok;
@@ -209,6 +244,8 @@ publish_on_node(Node) when is_atom(Node) ->
update_publish_nodes(Ns) ->
request({update_publish_nodes, Ns}).
+-spec connect_node(Node) -> boolean() | ignored when
+ Node :: node().
%% explicit connects
connect_node(Node) when is_atom(Node) ->
request({connect, normal, Node}).
diff --git a/lib/kernel/src/os.erl b/lib/kernel/src/os.erl
index d1feae771d..f6769df585 100644
--- a/lib/kernel/src/os.erl
+++ b/lib/kernel/src/os.erl
@@ -24,7 +24,10 @@
-include("file.hrl").
--spec type() -> 'vxworks' | {'unix',atom()} | {'win32',atom()} | {'ose',atom()}.
+-spec type() -> vxworks | {Osfamily, Osname} when
+ Osfamily :: unix | win32,
+ Osname :: atom().
+
type() ->
case erlang:system_info(os_type) of
{vxworks, _} ->
@@ -32,18 +35,27 @@ type() ->
Else -> Else
end.
--spec version() -> string() | {non_neg_integer(),non_neg_integer(),non_neg_integer()}.
+-spec version() -> VersionString | {Major, Minor, Release} when
+ VersionString :: string(),
+ Major :: non_neg_integer(),
+ Minor :: non_neg_integer(),
+ Release :: non_neg_integer().
version() ->
erlang:system_info(os_version).
--spec find_executable(string()) -> string() | 'false'.
+-spec find_executable(Name) -> Filename | 'false' when
+ Name :: string(),
+ Filename :: string().
find_executable(Name) ->
case os:getenv("PATH") of
false -> find_executable(Name, []);
Path -> find_executable(Name, Path)
end.
--spec find_executable(string(), string()) -> string() | 'false'.
+-spec find_executable(Name, Path) -> Filename | 'false' when
+ Name :: string(),
+ Path :: string(),
+ Filename :: string().
find_executable(Name, Path) ->
Extensions = extensions(),
case filename:pathtype(Name) of
@@ -147,7 +159,8 @@ extensions() ->
end.
%% Executes the given command in the default shell for the operating system.
--spec cmd(atom() | string() | [string()]) -> string().
+-spec cmd(Command) -> string() when
+ Command :: atom() | io_lib:chars().
cmd(Cmd) ->
validate(Cmd),
case type() of
diff --git a/lib/kernel/src/pg2.erl b/lib/kernel/src/pg2.erl
index 956a900adc..0d5838716e 100644
--- a/lib/kernel/src/pg2.erl
+++ b/lib/kernel/src/pg2.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -30,17 +30,19 @@
%%% Exported functions
%%%
--spec start_link() -> {'ok', pid()} | {'error', term()}.
+-spec start_link() -> {'ok', pid()} | {'error', any()}.
start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
--spec start() -> {'ok', pid()} | {'error', term()}.
+-spec start() -> {'ok', pid()} | {'error', any()}.
start() ->
ensure_started().
--spec create(term()) -> 'ok'.
+-type name() :: any().
+
+-spec create(Name :: name()) -> 'ok'.
create(Name) ->
ensure_started(),
@@ -55,9 +57,7 @@ create(Name) ->
ok
end.
--type name() :: term().
-
--spec delete(name()) -> 'ok'.
+-spec delete(Name :: name()) -> 'ok'.
delete(Name) ->
ensure_started(),
@@ -67,7 +67,8 @@ delete(Name) ->
end),
ok.
--spec join(name(), pid()) -> 'ok' | {'error', {'no_such_group', term()}}.
+-spec join(Name, Pid :: pid()) -> 'ok' | {'error', {'no_such_group', Name}}
+ when Name :: name().
join(Name, Pid) when is_pid(Pid) ->
ensure_started(),
@@ -83,7 +84,8 @@ join(Name, Pid) when is_pid(Pid) ->
ok
end.
--spec leave(name(), pid()) -> 'ok' | {'error', {'no_such_group', name()}}.
+-spec leave(Name, Pid :: pid()) -> 'ok' | {'error', {'no_such_group', Name}}
+ when Name :: name().
leave(Name, Pid) when is_pid(Pid) ->
ensure_started(),
@@ -99,10 +101,9 @@ leave(Name, Pid) when is_pid(Pid) ->
ok
end.
--type get_members_ret() :: [pid()] | {'error', {'no_such_group', name()}}.
+-spec get_members(Name) -> [pid()] | {'error', {'no_such_group', Name}}
+ when Name :: name().
--spec get_members(name()) -> get_members_ret().
-
get_members(Name) ->
ensure_started(),
case ets:member(pg2_table, {group, Name}) of
@@ -112,7 +113,8 @@ get_members(Name) ->
{error, {no_such_group, Name}}
end.
--spec get_local_members(name()) -> get_members_ret().
+-spec get_local_members(Name) -> [pid()] | {'error', {'no_such_group', Name}}
+ when Name :: name().
get_local_members(Name) ->
ensure_started(),
@@ -123,15 +125,15 @@ get_local_members(Name) ->
{error, {no_such_group, Name}}
end.
--spec which_groups() -> [name()].
+-spec which_groups() -> [Name :: name()].
which_groups() ->
ensure_started(),
all_groups().
--type gcp_error_reason() :: {'no_process', term()} | {'no_such_group', term()}.
-
--spec get_closest_pid(term()) -> pid() | {'error', gcp_error_reason()}.
+-spec get_closest_pid(Name) -> pid() | {'error', Reason} when
+ Name :: name(),
+ Reason :: {'no_process', Name} | {'no_such_group', Name}.
get_closest_pid(Name) ->
case get_local_members(Name) of
@@ -157,7 +159,9 @@ get_closest_pid(Name) ->
-record(state, {}).
--spec init([]) -> {'ok', #state{}}.
+-opaque state() :: #state{}.
+
+-spec init(Arg :: []) -> {'ok', state()}.
init([]) ->
Ns = nodes(),
@@ -169,13 +173,13 @@ init([]) ->
pg2_table = ets:new(pg2_table, [ordered_set, protected, named_table]),
{ok, #state{}}.
--type call() :: {'create', name()}
- | {'delete', name()}
- | {'join', name(), pid()}
- | {'leave', name(), pid()}.
-
--spec handle_call(call(), _, #state{}) ->
- {'reply', 'ok', #state{}}.
+-spec handle_call(Call :: {'create', Name}
+ | {'delete', Name}
+ | {'join', Name, Pid :: pid()}
+ | {'leave', Name, Pid :: pid()},
+ From :: {pid(),Tag :: any()},
+ State :: state()) -> {'reply', 'ok', state()}
+ when Name :: name().
handle_call({create, Name}, _From, S) ->
assure_group(Name),
@@ -195,11 +199,10 @@ handle_call(Request, From, S) ->
[Request, From]),
{noreply, S}.
--type all_members() :: [[name(),...]].
--type cast() :: {'exchange', node(), all_members()}
- | {'del_member', name(), pid()}.
-
--spec handle_cast(cast(), #state{}) -> {'noreply', #state{}}.
+-spec handle_cast(Cast :: {'exchange', node(), Names :: [[Name,...]]}
+ | {'del_member', Name, Pid :: pid()},
+ State :: state()) -> {'noreply', state()}
+ when Name :: name().
handle_cast({exchange, _Node, List}, S) ->
store(List),
@@ -208,7 +211,8 @@ handle_cast(_, S) ->
%% Ignore {del_member, Name, Pid}.
{noreply, S}.
--spec handle_info(tuple(), #state{}) -> {'noreply', #state{}}.
+-spec handle_info(Tuple :: tuple(), State :: state()) ->
+ {'noreply', state()}.
handle_info({'DOWN', MonitorRef, process, _Pid, _Info}, S) ->
member_died(MonitorRef),
@@ -222,7 +226,7 @@ handle_info({new_pg2, Node}, S) ->
handle_info(_, S) ->
{noreply, S}.
--spec terminate(term(), #state{}) -> 'ok'.
+-spec terminate(Reason :: any(), State :: state()) -> 'ok'.
terminate(_Reason, _S) ->
true = ets:delete(pg2_table),
diff --git a/lib/kernel/src/rpc.erl b/lib/kernel/src/rpc.erl
index e09acb5024..be35f99ed2 100644
--- a/lib/kernel/src/rpc.erl
+++ b/lib/kernel/src/rpc.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -263,14 +263,28 @@ proxy_user_flush() ->
%% THE rpc client interface
--spec call(node(), atom(), atom(), [term()]) -> term().
+-spec call(Node, Module, Function, Args) -> Res | {badrpc, Reason} when
+ Node :: node(),
+ Module :: module(),
+ Function :: atom(),
+ Args :: [term()],
+ Res :: term(),
+ Reason :: term().
call(N,M,F,A) when node() =:= N -> %% Optimize local call
local_call(M, F, A);
call(N,M,F,A) ->
do_call(N, {call,M,F,A,group_leader()}, infinity).
--spec call(node(), atom(), atom(), [term()], timeout()) -> term().
+-spec call(Node, Module, Function, Args, Timeout) ->
+ Res | {badrpc, Reason} when
+ Node :: node(),
+ Module :: module(),
+ Function :: atom(),
+ Args :: [term()],
+ Res :: term(),
+ Reason :: term(),
+ Timeout :: timeout().
call(N,M,F,A,_Timeout) when node() =:= N -> %% Optimize local call
local_call(M,F,A);
@@ -279,14 +293,28 @@ call(N,M,F,A,infinity) ->
call(N,M,F,A,Timeout) when is_integer(Timeout), Timeout >= 0 ->
do_call(N, {call,M,F,A,group_leader()}, Timeout).
--spec block_call(node(), atom(), atom(), [term()]) -> term().
+-spec block_call(Node, Module, Function, Args) -> Res | {badrpc, Reason} when
+ Node :: node(),
+ Module :: module(),
+ Function :: atom(),
+ Args :: [term()],
+ Res :: term(),
+ Reason :: term().
block_call(N,M,F,A) when node() =:= N -> %% Optimize local call
local_call(M,F,A);
block_call(N,M,F,A) ->
do_call(N, {block_call,M,F,A,group_leader()}, infinity).
--spec block_call(node(), atom(), atom(), [term()], timeout()) -> term().
+-spec block_call(Node, Module, Function, Args, Timeout) ->
+ Res | {badrpc, Reason} when
+ Node :: node(),
+ Module :: module(),
+ Function :: atom(),
+ Args :: [term()],
+ Res :: term(),
+ Reason :: term(),
+ Timeout :: timeout().
block_call(N,M,F,A,_Timeout) when node() =:= N -> %% Optimize local call
local_call(M, F, A);
@@ -339,7 +367,13 @@ rpc_check(X) -> X.
%% The entire call is packed into an atomic transaction which
%% either succeeds or fails, i.e. never hangs (unless the server itself hangs).
--spec server_call(node(), atom(), term(), term()) -> term() | {'error', 'nodedown'}.
+-spec server_call(Node, Name, ReplyWrapper, Msg) -> Reply | {error, Reason} when
+ Node :: node(),
+ Name :: atom(),
+ ReplyWrapper :: term(),
+ Msg :: term(),
+ Reply :: term(),
+ Reason :: nodedown.
server_call(Node, Name, ReplyWrapper, Msg)
when is_atom(Node), is_atom(Name) ->
@@ -362,7 +396,11 @@ server_call(Node, Name, ReplyWrapper, Msg)
end
end.
--spec cast(node(), atom(), atom(), [term()]) -> 'true'.
+-spec cast(Node, Module, Function, Args) -> true when
+ Node :: node(),
+ Module :: module(),
+ Function :: atom(),
+ Args :: [term()].
cast(Node, Mod, Fun, Args) when Node =:= node() ->
catch spawn(Mod, Fun, Args),
@@ -373,12 +411,17 @@ cast(Node, Mod, Fun, Args) ->
%% Asynchronous broadcast, returns nothing, it's just send'n prey
--spec abcast(atom(), term()) -> 'abcast'.
+-spec abcast(Name, Msg) -> abcast when
+ Name :: atom(),
+ Msg :: term().
abcast(Name, Mess) ->
abcast([node() | nodes()], Name, Mess).
--spec abcast([node()], atom(), term()) -> 'abcast'.
+-spec abcast(Nodes, Name, Msg) -> abcast when
+ Nodes :: [node()],
+ Name :: atom(),
+ Msg :: term().
abcast([Node|Tail], Name, Mess) ->
Dest = {Name,Node},
@@ -396,23 +439,39 @@ abcast([], _,_) -> abcast.
%% message when we return from the call, we can't know that they have
%% processed the message though.
--spec sbcast(atom(), term()) -> {[node()], [node()]}.
+-spec sbcast(Name, Msg) -> {GoodNodes, BadNodes} when
+ Name :: atom(),
+ Msg :: term(),
+ GoodNodes :: [node()],
+ BadNodes :: [node()].
sbcast(Name, Mess) ->
sbcast([node() | nodes()], Name, Mess).
--spec sbcast([node()], atom(), term()) -> {[node()], [node()]}.
+-spec sbcast(Nodes, Name, Msg) -> {GoodNodes, BadNodes} when
+ Name :: atom(),
+ Msg :: term(),
+ Nodes :: [node()],
+ GoodNodes :: [node()],
+ BadNodes :: [node()].
sbcast(Nodes, Name, Mess) ->
Monitors = send_nodes(Nodes, ?NAME, {sbcast, Name, Mess}, []),
rec_nodes(?NAME, Monitors).
--spec eval_everywhere(atom(), atom(), [term()]) -> 'abcast'.
+-spec eval_everywhere(Module, Function, Args) -> abcast when
+ Module :: module(),
+ Function :: atom(),
+ Args :: [term()].
eval_everywhere(Mod, Fun, Args) ->
eval_everywhere([node() | nodes()] , Mod, Fun, Args).
--spec eval_everywhere([node()], atom(), atom(), [term()]) -> 'abcast'.
+-spec eval_everywhere(Nodes, Module, Function, Args) -> abcast when
+ Nodes :: [node()],
+ Module :: module(),
+ Function :: atom(),
+ Args :: [term()].
eval_everywhere(Nodes, Mod, Fun, Args) ->
gen_server:abcast(Nodes, ?NAME, {cast,Mod,Fun,Args,group_leader()}).
@@ -453,20 +512,45 @@ unmonitor(Ref) when is_reference(Ref) ->
%% Call apply(M,F,A) on all nodes in parallel
--spec multicall(atom(), atom(), [term()]) -> {[_], [node()]}.
+-spec multicall(Module, Function, Args) -> {ResL, BadNodes} when
+ Module :: module(),
+ Function :: atom(),
+ Args :: [term()],
+ ResL :: [term()],
+ BadNodes :: [node()].
multicall(M, F, A) ->
multicall(M, F, A, infinity).
--spec multicall([node()], atom(), atom(), [term()]) -> {[_], [node()]}
- ; (atom(), atom(), [term()], timeout()) -> {[_], [node()]}.
+-spec multicall(Nodes, Module, Function, Args) -> {ResL, BadNodes} when
+ Nodes :: [node()],
+ Module :: module(),
+ Function :: atom(),
+ Args :: [term()],
+ ResL :: [term()],
+ BadNodes :: [node()];
+ (Module, Function, Args, Timeout) -> {ResL, BadNodes} when
+ Module :: module(),
+ Function :: atom(),
+ Args :: [term()],
+ Timeout :: timeout(),
+ ResL :: [term()],
+ BadNodes :: [node()].
multicall(Nodes, M, F, A) when is_list(Nodes) ->
multicall(Nodes, M, F, A, infinity);
multicall(M, F, A, Timeout) ->
multicall([node() | nodes()], M, F, A, Timeout).
--spec multicall([node()], atom(), atom(), [term()], timeout()) -> {[_], [node()]}.
+-spec multicall(Nodes, Module, Function, Args, Timeout) ->
+ {ResL, BadNodes} when
+ Nodes :: [node()],
+ Module :: module(),
+ Function :: atom(),
+ Args :: [term()],
+ Timeout :: timeout(),
+ ResL :: [term()],
+ BadNodes :: [node()].
multicall(Nodes, M, F, A, infinity)
when is_list(Nodes), is_atom(M), is_atom(F), is_list(A) ->
@@ -495,12 +579,21 @@ do_multicall(Nodes, M, F, A, Timeout) ->
%%
%% There is no apparent order among the replies.
--spec multi_server_call(atom(), term()) -> {[_], [node()]}.
+-spec multi_server_call(Name, Msg) -> {Replies, BadNodes} when
+ Name :: atom(),
+ Msg :: term(),
+ Replies :: [Reply :: term()],
+ BadNodes :: [node()].
multi_server_call(Name, Msg) ->
multi_server_call([node() | nodes()], Name, Msg).
--spec multi_server_call([node()], atom(), term()) -> {[_], [node()]}.
+-spec multi_server_call(Nodes, Name, Msg) -> {Replies, BadNodes} when
+ Nodes :: [node()],
+ Name :: atom(),
+ Msg :: term(),
+ Replies :: [Reply :: term()],
+ BadNodes :: [node()].
multi_server_call(Nodes, Name, Msg)
when is_list(Nodes), is_atom(Name) ->
@@ -509,9 +602,22 @@ multi_server_call(Nodes, Name, Msg)
%% Deprecated functions. Were only needed when communicating with R6 nodes.
+-spec safe_multi_server_call(Name, Msg) -> {Replies, BadNodes} when
+ Name :: atom(),
+ Msg :: term(),
+ Replies :: [Reply :: term()],
+ BadNodes :: [node()].
+
safe_multi_server_call(Name, Msg) ->
multi_server_call(Name, Msg).
+-spec safe_multi_server_call(Nodes, Name, Msg) -> {Replies, BadNodes} when
+ Nodes :: [node()],
+ Name :: atom(),
+ Msg :: term(),
+ Replies :: [Reply :: term()],
+ BadNodes :: [node()].
+
safe_multi_server_call(Nodes, Name, Msg) ->
multi_server_call(Nodes, Name, Msg).
@@ -539,7 +645,14 @@ rec_nodes(Name, [{N,R} | Tail], Badnodes, Replies) ->
%% rpc's towards the same node. I.e. it returns immediately and
%% it returns a Key that can be used in a subsequent yield(Key).
--spec async_call(node(), atom(), atom(), [term()]) -> pid().
+-opaque key() :: pid().
+
+-spec async_call(Node, Module, Function, Args) -> Key when
+ Node :: node(),
+ Module :: module(),
+ Function :: atom(),
+ Args :: [term()],
+ Key :: key().
async_call(Node, Mod, Fun, Args) ->
ReplyTo = self(),
@@ -549,20 +662,27 @@ async_call(Node, Mod, Fun, Args) ->
ReplyTo ! {self(), {promise_reply, R}} %% self() is key
end).
--spec yield(pid()) -> term().
+-spec yield(Key) -> {value, Val} | timeout when
+ Key :: key(),
+ Val :: (Res :: term()) | {badrpc, Reason :: term()}.
yield(Key) when is_pid(Key) ->
{value,R} = do_yield(Key, infinity),
R.
--spec nb_yield(pid(), timeout()) -> {'value', _} | 'timeout'.
+-spec nb_yield(Key, Timeout) -> {value, Val} | timeout when
+ Key :: key(),
+ Timeout :: timeout(),
+ Val :: (Res :: term()) | {badrpc, Reason :: term()}.
nb_yield(Key, infinity=Inf) when is_pid(Key) ->
do_yield(Key, Inf);
nb_yield(Key, Timeout) when is_pid(Key), is_integer(Timeout), Timeout >= 0 ->
do_yield(Key, Timeout).
--spec nb_yield(pid()) -> {'value', _} | 'timeout'.
+-spec nb_yield(Key) -> {value, Val} | timeout when
+ Key :: key(),
+ Val :: (Res :: term()) | {badrpc, Reason :: term()}.
nb_yield(Key) when is_pid(Key) ->
do_yield(Key, 0).
@@ -582,7 +702,12 @@ do_yield(Key, Timeout) ->
%% ArgL === [{M,F,Args},........]
%% Returns a lists of the evaluations in the same order as
%% given to ArgL
--spec parallel_eval([{atom(), atom(), [_]}]) -> [_].
+-spec parallel_eval(FuncCalls) -> ResL when
+ FuncCalls :: [{Module, Function, Args}],
+ Module :: module(),
+ Function :: atom(),
+ Args :: [term()],
+ ResL :: [term()].
parallel_eval(ArgL) ->
Nodes = [node() | nodes()],
@@ -599,7 +724,13 @@ map_nodes([{M,F,A}|Tail],[Node|MoreNodes], Original) ->
%% Parallel version of lists:map/3 with exactly the same
%% arguments and return value as lists:map/3,
%% except that it calls exit/1 if a network error occurs.
--spec pmap({atom(),atom()}, [term()], [term()]) -> [term()].
+-spec pmap(FuncSpec, ExtraArgs, List1) -> List2 when
+ FuncSpec :: {Module,Function},
+ Module :: module(),
+ Function :: atom(),
+ ExtraArgs :: [term()],
+ List1 :: [Elem :: term()],
+ List2 :: [term()].
pmap({M,F}, As, List) ->
check(parallel_eval(build_args(M,F,As, List, [])), []).
@@ -616,15 +747,20 @@ check([], Ack) -> Ack.
%% location transparent version of process_info
--spec pinfo(pid()) -> [{atom(), _}] | 'undefined'.
+-spec pinfo(Pid) -> [{Item, Info}] | undefined when
+ Pid :: pid(),
+ Item :: atom(),
+ Info :: term().
pinfo(Pid) when node(Pid) =:= node() ->
process_info(Pid);
pinfo(Pid) ->
call(node(Pid), erlang, process_info, [Pid]).
--spec pinfo(pid(), Item) -> {Item, _} | 'undefined' | []
- when is_subtype(Item, atom()).
+-spec pinfo(Pid, Item) -> {Item, Info} | undefined | [] when
+ Pid :: pid(),
+ Item :: atom(),
+ Info :: term().
pinfo(Pid, Item) when node(Pid) =:= node() ->
process_info(Pid, Item);
diff --git a/lib/kernel/src/seq_trace.erl b/lib/kernel/src/seq_trace.erl
index 78c3040f21..ea5da2de1c 100644
--- a/lib/kernel/src/seq_trace.erl
+++ b/lib/kernel/src/seq_trace.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -38,15 +38,17 @@
-type flag() :: 'send' | 'receive' | 'print' | 'timestamp'.
-type component() :: 'label' | 'serial' | flag().
--type value() :: non_neg_integer()
- | {non_neg_integer(), non_neg_integer()}
- | boolean().
--type token_pair() :: {component(), value()}.
+-type value() :: (Integer :: non_neg_integer())
+ | {Previous :: non_neg_integer(),
+ Current :: non_neg_integer()}
+ | (Bool :: boolean()).
%%---------------------------------------------------------------------------
--type token() :: [] | {integer(), boolean(), _, _, _}.
--spec set_token(token()) -> token() | 'ok'.
+-opaque token() :: {integer(), boolean(), _, _, _}.
+-spec set_token(Token) -> PreviousToken | 'ok' when
+ Token :: [] | token(),
+ PreviousToken :: [] | token().
set_token([]) ->
erlang:seq_trace(sequential_trace_token,[]);
@@ -58,28 +60,35 @@ set_token({Flags,Label,Serial,_From,Lastcnt}) ->
%% expects that, the BIF can however "unofficially" handle atoms as well, and
%% atoms can be used if only Erlang nodes are involved
--spec set_token(component(), value()) -> token_pair().
+-spec set_token(Component, Val) -> {Component, OldVal} when
+ Component :: component(),
+ Val :: value(),
+ OldVal :: value().
set_token(Type, Val) ->
erlang:seq_trace(Type, Val).
--spec get_token() -> term().
+-spec get_token() -> [] | token().
get_token() ->
element(2,process_info(self(),sequential_trace_token)).
--spec get_token(component()) -> token_pair().
-
+-spec get_token(Component) -> {Component, Val} when
+ Component :: component(),
+ Val :: value().
get_token(Type) ->
erlang:seq_trace_info(Type).
--spec print(term()) -> 'ok'.
+-spec print(TraceInfo) -> 'ok' when
+ TraceInfo :: term().
print(Term) ->
erlang:seq_trace_print(Term),
ok.
--spec print(integer(), term()) -> 'ok'.
+-spec print(Label, TraceInfo) -> 'ok' when
+ Label :: integer(),
+ TraceInfo :: term().
print(Label, Term) when is_atom(Label) ->
erlang:error(badarg, [Label, Term]);
@@ -94,14 +103,17 @@ reset_trace() ->
%% reset_trace(Pid) -> % this might be a useful function too
--type tracer() :: pid() | port() | 'false'.
+-type tracer() :: (Pid :: pid()) | port() | 'false'.
--spec set_system_tracer(tracer()) -> tracer().
+-spec set_system_tracer(Tracer) -> OldTracer when
+ Tracer :: tracer(),
+ OldTracer :: tracer().
set_system_tracer(Pid) ->
erlang:system_flag(sequential_tracer, Pid).
--spec get_system_tracer() -> tracer().
+-spec get_system_tracer() -> Tracer when
+ Tracer :: tracer().
get_system_tracer() ->
element(2, erlang:system_info(sequential_tracer)).
diff --git a/lib/kernel/src/wrap_log_reader.erl b/lib/kernel/src/wrap_log_reader.erl
index fabaa07752..c41e0091e4 100644
--- a/lib/kernel/src/wrap_log_reader.erl
+++ b/lib/kernel/src/wrap_log_reader.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -41,6 +41,8 @@
first_no :: non_neg_integer() | 'one' % first read file number
}).
+-opaque continuation() :: #wrap_reader{}.
+
%%
%% Exported functions
%%
@@ -50,9 +52,11 @@
%% is not yet reached, we are on the first 'round' of filling the wrap
%% files.
--type open_ret() :: {'ok', #wrap_reader{}} | {'error', tuple()}.
+-type open_ret() :: {'ok', Continuation :: continuation()}
+ | {'error', Reason :: tuple()}.
--spec open(atom() | string()) -> open_ret().
+-spec open(Filename) -> open_ret() when
+ Filename :: string() | atom().
open(File) when is_atom(File) ->
open(atom_to_list(File));
@@ -77,7 +81,9 @@ open(File) when is_list(File) ->
Error
end.
--spec open(atom() | string(), integer()) -> open_ret().
+-spec open(Filename, N) -> open_ret() when
+ Filename :: string() | atom(),
+ N :: integer().
open(File, FileNo) when is_atom(File), is_integer(FileNo) ->
open(atom_to_list(File), FileNo);
@@ -100,22 +106,29 @@ open(File, FileNo) when is_list(File), is_integer(FileNo) ->
Error
end.
--spec close(#wrap_reader{}) -> 'ok' | {'error', atom()}.
+-spec close(Continuation) -> 'ok' | {'error', Reason} when
+ Continuation :: continuation(),
+ Reason :: file:posix().
close(#wrap_reader{fd = FD}) ->
file:close(FD).
--type chunk_ret() :: {#wrap_reader{}, [term()]}
- | {#wrap_reader{}, [term()], non_neg_integer()}
- | {#wrap_reader{}, 'eof'}
- | {'error', term()}.
+-type chunk_ret() :: {Continuation2, Terms :: [term()]}
+ | {Continuation2,
+ Terms :: [term()],
+ Badbytes :: non_neg_integer()}
+ | {Continuation2, 'eof'}
+ | {'error', Reason :: term()}.
--spec chunk(#wrap_reader{}) -> chunk_ret().
+-spec chunk(Continuation) -> chunk_ret() when
+ Continuation :: continuation().
chunk(WR = #wrap_reader{}) ->
chunk(WR, ?MAX_CHUNK_SIZE, 0).
--spec chunk(#wrap_reader{}, 'infinity' | pos_integer()) -> chunk_ret().
+-spec chunk(Continuation, N) -> chunk_ret() when
+ Continuation :: continuation(),
+ N :: infinity | pos_integer().
chunk(WR = #wrap_reader{}, infinity) ->
chunk(WR, ?MAX_CHUNK_SIZE, 0);
diff --git a/lib/mnesia/src/mnesia_dumper.erl b/lib/mnesia/src/mnesia_dumper.erl
index 644133cf5d..55b9946ae9 100644
--- a/lib/mnesia/src/mnesia_dumper.erl
+++ b/lib/mnesia/src/mnesia_dumper.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -871,7 +871,11 @@ insert_op(Tid, _, {op, add_index, Pos, TabDef}, InPlace, InitBy) ->
startup ->
ignore;
_ ->
- mnesia_index:init_indecies(Tab, Storage, [Pos])
+ case val({Tab,where_to_read}) of
+ nowhere -> ignore;
+ _ ->
+ mnesia_index:init_indecies(Tab, Storage, [Pos])
+ end
end;
insert_op(Tid, _, {op, del_index, Pos, TabDef}, InPlace, InitBy) ->
diff --git a/lib/mnesia/src/mnesia_schema.erl b/lib/mnesia/src/mnesia_schema.erl
index d1d892a387..f33a6c7a84 100644
--- a/lib/mnesia/src/mnesia_schema.erl
+++ b/lib/mnesia/src/mnesia_schema.erl
@@ -1734,7 +1734,10 @@ prepare_op(_Tid, {op, announce_im_running, Node, SchemaDef, Running, RemoteRunni
Node == node() -> %% Announce has already run on local node
ignore; %% from do_merge_schema
true ->
- NewNodes = mnesia_lib:uniq(Running++RemoteRunning) -- val({current,db_nodes}),
+ %% If a node has restarted it may still linger in db_nodes,
+ %% but have been removed from recover_nodes
+ Current = mnesia_lib:intersect(val({current,db_nodes}), [node()|val(recover_nodes)]),
+ NewNodes = mnesia_lib:uniq(Running++RemoteRunning) -- Current,
mnesia_lib:set(prepare_op, {announce_im_running,NewNodes}),
announce_im_running(NewNodes, SchemaCs)
end,
diff --git a/lib/mnesia/test/.gitignore b/lib/mnesia/test/.gitignore
new file mode 100644
index 0000000000..1e9a9933ed
--- /dev/null
+++ b/lib/mnesia/test/.gitignore
@@ -0,0 +1,9 @@
+
+
+# Test generates
+MnesiaCore*
+Mnesia.*
+
+tempfile*
+mnesia_test_case_info
+test_log* \ No newline at end of file
diff --git a/lib/mnesia/test/mnesia_durability_test.erl b/lib/mnesia/test/mnesia_durability_test.erl
index 55205d1222..2fee72f066 100644
--- a/lib/mnesia/test/mnesia_durability_test.erl
+++ b/lib/mnesia/test/mnesia_durability_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -119,8 +119,8 @@ load_latest_data(Config) when is_list(Config) ->
?match([], mnesia_test_lib:kill_mnesia([N2])),
?match(ok, mnesia:dirty_write(Rec1)),
- ?match([], mnesia_test_lib:kill_mnesia([N1])),
?match([], mnesia_test_lib:kill_mnesia([N3])),
+ ?match([], mnesia_test_lib:kill_mnesia([N1])),
?match([], mnesia_test_lib:start_mnesia([N2], [])),
%% Should wait for N1
diff --git a/lib/mnesia/test/mnesia_qlc_test.erl b/lib/mnesia/test/mnesia_qlc_test.erl
index 141de71d01..5f46840ae9 100644
--- a/lib/mnesia/test/mnesia_qlc_test.erl
+++ b/lib/mnesia/test/mnesia_qlc_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -70,6 +70,7 @@ init_testcases(Type,Config) ->
end,
All = fun() -> [Write(Id) || Id <- lists:seq(1,10)], ok end,
?match({atomic, ok}, mnesia:sync_transaction(All)),
+ ?match({atomic, [{b, {b,100-1}, 1}]}, mnesia:transaction(fun() -> mnesia:read({b, {b, 99}}) end)),
Nodes.
%% Test cases
diff --git a/lib/mnesia/test/mnesia_test_lib.erl b/lib/mnesia/test/mnesia_test_lib.erl
index 182c240084..9da45975d5 100644
--- a/lib/mnesia/test/mnesia_test_lib.erl
+++ b/lib/mnesia/test/mnesia_test_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -413,32 +413,28 @@ test_driver([T|TestCases], Config) ->
[L1|L2];
test_driver({Module, TestCases}, Config) when is_list(TestCases)->
test_driver(default_module(Module, TestCases), Config);
-test_driver({_, {Module, TestCase}}, Config) ->
- test_driver({Module, TestCase}, Config);
+test_driver({Module, all}, Config) ->
+ get_suite(Module, all, Config);
+test_driver({Module, G={group, _}}, Config) ->
+ get_suite(Module, G, Config);
+test_driver({_, {group, Module, Group}}, Config) ->
+ get_suite(Module, {group, Group}, Config);
+
test_driver({Module, TestCase}, Config) ->
Sec = timer:seconds(1) * 1000,
- case get_suite(Module, TestCase) of
- [] when Config == suite ->
+ case Config of
+ suite ->
{Module, TestCase, 'IMPL'};
- [] ->
+ _ ->
log("Eval test case: ~w~n", [{Module, TestCase}]),
- {T, Res} =
- timer:tc(?MODULE, eval_test_case, [Module, TestCase, Config]),
- log("Tested ~w in ~w sec~n", [TestCase, T div Sec]),
- {T div Sec, Res};
- Suite when is_list(Suite), Config == suite ->
- Res = test_driver(default_module(Module, Suite), Config),
- {{Module, TestCase}, Res};
- Suite when is_list(Suite) ->
- log("Expand test case ~w~n", [{Module, TestCase}]),
- Def = default_module(Module, Suite),
- {T, Res} = timer:tc(?MODULE, test_driver, [Def, Config]),
- {T div Sec, {{Module, TestCase}, Res}};
- 'NYI' when Config == suite ->
- {Module, TestCase, 'NYI'};
- 'NYI' ->
- log("<WARNING> Test case ~w NYI~n", [{Module, TestCase}]),
- {0, {skip, {Module, TestCase}, "NYI"}}
+ try timer:tc(?MODULE, eval_test_case, [Module, TestCase, Config]) of
+ {T, Res} ->
+ log("Tested ~w in ~w sec~n", [TestCase, T div Sec]),
+ {T div Sec, Res}
+ catch error:function_clause ->
+ log("<WARNING> Test case ~w NYI~n", [{Module, TestCase}]),
+ {0, {skip, {Module, TestCase}, "NYI"}}
+ end
end;
test_driver(TestCase, Config) ->
DefaultModule = mnesia_SUITE,
@@ -449,18 +445,50 @@ test_driver(TestCase, Config) ->
default_module(DefaultModule, TestCases) when is_list(TestCases) ->
Fun = fun(T) ->
case T of
+ {group, _} -> {true, {DefaultModule, T}};
{_, _} -> true;
T -> {true, {DefaultModule, T}}
end
end,
lists:zf(Fun, TestCases).
+get_suite(Module, TestCase, Config) ->
+ case get_suite(Module, TestCase) of
+ Suite when is_list(Suite), Config == suite ->
+ Res = test_driver(default_module(Module, Suite), Config),
+ {{Module, TestCase}, Res};
+ Suite when is_list(Suite) ->
+ log("Expand test case ~w~n", [{Module, TestCase}]),
+ Def = default_module(Module, Suite),
+ {T, Res} = timer:tc(?MODULE, test_driver, [Def, Config]),
+ Sec = timer:seconds(1) * 1000,
+ {T div Sec, {{Module, TestCase}, Res}};
+ 'NYI' when Config == suite ->
+ {Module, TestCase, 'NYI'};
+ 'NYI' ->
+ log("<WARNING> Test case ~w NYI~n", [{Module, TestCase}]),
+ {0, {skip, {Module, TestCase}, "NYI"}}
+ end.
+
%% Returns a list (possibly empty) or the atom 'NYI'
-get_suite(Mod, Fun) ->
- case catch (apply(Mod, Fun, [suite])) of
+get_suite(Mod, {group, Suite}) ->
+ try
+ Groups = Mod:groups(),
+ {_, _, TCList} = lists:keyfind(Suite, 1, Groups),
+ TCList
+ catch
+ _:Reason ->
+ io:format("Not implemented ~p ~p (~p ~p)~n",
+ [Mod,Suite,Reason, erlang:get_stacktrace()]),
+ 'NYI'
+ end;
+get_suite(Mod, all) ->
+ case catch (apply(Mod, all, [])) of
{'EXIT', _} -> 'NYI';
List when is_list(List) -> List
- end.
+ end;
+get_suite(_Mod, _Fun) ->
+ [].
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -503,9 +531,13 @@ wait_for_evaluator(Pid, Mod, Fun, Config) ->
test_case_evaluator(Mod, Fun, [Config]) ->
NewConfig = Mod:init_per_testcase(Fun, Config),
- R = apply(Mod, Fun, [NewConfig]),
- Mod:end_per_testcase(Fun, NewConfig),
- exit({test_case_ok, R}).
+ try
+ R = apply(Mod, Fun, [NewConfig]),
+ Mod:end_per_testcase(Fun, NewConfig),
+ exit({test_case_ok, R})
+ catch error:function_clause ->
+ exit({skipped, 'NYI'})
+ end.
activity_evaluator(Coordinator) ->
activity_evaluator_loop(Coordinator),
diff --git a/lib/mnesia/test/mnesia_trans_access_test.erl b/lib/mnesia/test/mnesia_trans_access_test.erl
index 55ba4dd761..ca3f0fbf49 100644
--- a/lib/mnesia/test/mnesia_trans_access_test.erl
+++ b/lib/mnesia/test/mnesia_trans_access_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -1102,9 +1102,9 @@ create_live_table_index_disc_only(Config) when is_list(Config) ->
create_live_table_index(Config, disc_only_copies).
create_live_table_index(Config, Storage) ->
- [Node1] = Nodes = ?acquire_nodes(1, Config),
+ [N1,N2,N3] = Nodes = ?acquire_nodes(3, Config),
Tab = create_live_table_index,
- Schema = [{name, Tab}, {attributes, [k, v]}, {Storage, [Node1]}],
+ Schema = [{name, Tab}, {attributes, [k, v]}, {Storage, Nodes}],
?match({atomic, ok}, mnesia:create_table(Schema)),
ValPos = 3,
mnesia:dirty_write({Tab, 1, 2}),
@@ -1115,9 +1115,35 @@ create_live_table_index(Config, Storage) ->
end,
?match({atomic, ok}, mnesia:transaction(Fun)),
?match({atomic, ok}, mnesia:add_table_index(Tab, ValPos)),
+ IRead = fun() -> lists:sort(mnesia:index_read(Tab, 2, ValPos)) end,
+ ?match({atomic, [{Tab, 1, 2},{Tab, 2, 2}]}, mnesia:transaction(IRead)),
+ ?match({atomic, ok}, mnesia:del_table_index(Tab, ValPos)),
+
+ %% Bug when adding index when table is still unloaded
+ %% By setting load order we hopefully will trigger the bug
+ mnesia:change_table_copy_type(Tab, N2, ram_copies),
+ mnesia:change_table_copy_type(Tab, N3, ram_copies),
+ ?match({atomic,ok}, mnesia:change_table_copy_type(schema, N2, ram_copies)),
+ ?match({atomic,ok}, mnesia:change_table_copy_type(schema, N3, ram_copies)),
+
+ Create = fun(N) ->
+ TabN = list_to_atom("tab_" ++ integer_to_list(N)),
+ Def = [{ram_copies, Nodes}, {load_order, N}],
+ mnesia:create_table(TabN, Def)
+ end,
+
+ ?match([{atomic,ok}|_], [Create(N) || N <- lists:seq(1,50)]),
+
+ ?match([], mnesia_test_lib:stop_mnesia([N2,N3])),
+ ?match(ok, rpc:call(N2, mnesia, start, [[{extra_db_nodes,[N1]}]])),
+ ?match(ok, rpc:call(N3, mnesia, start, [[{extra_db_nodes,[N1]}]])),
+
+ ?match({atomic, ok}, mnesia:add_table_index(Tab, ValPos)),
+
+ ?match({atomic, [{Tab, 1, 2},{Tab, 2, 2}]}, mnesia:transaction(IRead)),
?match({atomic, [{Tab, 1, 2},{Tab, 2, 2}]},
- mnesia:transaction(fun() -> lists:sort(mnesia:index_read(Tab, 2, ValPos))
- end)),
+ rpc:call(N2, mnesia, transaction, [IRead])),
+
?verify_mnesia(Nodes, []).
%% Drop table index
diff --git a/lib/mnesia/test/mt.erl b/lib/mnesia/test/mt.erl
index f69c4a11fd..322bd52130 100644
--- a/lib/mnesia/test/mt.erl
+++ b/lib/mnesia/test/mt.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -76,17 +76,24 @@ resolve(Suite0) when is_atom(Suite0) ->
Suite when is_atom(Suite) ->
{Suite, all};
{Suite, Case} ->
- {Suite, Case}
+ {Suite, is_group(Suite,Case)}
end;
resolve({Suite0, Case}) when is_atom(Suite0), is_atom(Case) ->
case alias(Suite0) of
Suite when is_atom(Suite) ->
- {Suite, Case};
+ {Suite, is_group(Suite,Case)};
{Suite, Case2} ->
- {Suite, Case2}
+ {Suite, is_group(Suite,Case2)}
end;
resolve(List) when is_list(List) ->
[resolve(Case) || Case <- List].
+
+is_group(Mod, Case) ->
+ try {_,_,_} = lists:keyfind(Case, 1, Mod:groups()),
+ {group, Case}
+ catch _:{badmatch,_} ->
+ Case
+ end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Run one or more test cases
diff --git a/lib/stdlib/include/zip.hrl b/lib/stdlib/include/zip.hrl
index 2b5ddc1dfe..6e3ed9c78a 100644
--- a/lib/stdlib/include/zip.hrl
+++ b/lib/stdlib/include/zip.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -19,7 +19,7 @@
-record(zip_file, {
name :: string(), % file name
- info :: #file_info{},
+ info :: file:file_info(),
comment :: string(), % zip file comment
offset :: non_neg_integer(), % offset of file's local header in archive
comp_size :: non_neg_integer() % compressed size
diff --git a/lib/stdlib/src/array.erl b/lib/stdlib/src/array.erl
index 83576c9fd3..2f69e2b0a4 100644
--- a/lib/stdlib/src/array.erl
+++ b/lib/stdlib/src/array.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -163,17 +163,17 @@
-type array_indx() :: non_neg_integer().
--type array_opt() :: 'fixed' | non_neg_integer()
- | {'default', term()} | {'fixed', boolean()}
- | {'size', non_neg_integer()}.
+-type array_opt() :: {'fixed', boolean()} | 'fixed'
+ | {'default', Value :: term()}
+ | {'size', N :: non_neg_integer()}
+ | (N :: non_neg_integer()).
-type array_opts() :: array_opt() | [array_opt()].
--type indx_pair() :: {array_indx(), term()}.
+-type indx_pair() :: {Index :: array_indx(), Value :: term()}.
-type indx_pairs() :: [indx_pair()].
%%--------------------------------------------------------------------------
-%% @spec () -> array()
%% @doc Create a new, extendible array with initial size zero.
%% @equiv new([])
%%
@@ -185,7 +185,6 @@
new() ->
new([]).
-%% @spec (Options::term()) -> array()
%% @doc Create a new array according to the given options. By default,
%% the array is extendible and has initial size zero. Array indices
%% start at 0.
@@ -224,12 +223,11 @@ new() ->
%% @see from_list/2
%% @see fix/1
--spec new(array_opts()) -> array().
+-spec new(Options :: array_opts()) -> array().
new(Options) ->
new_0(Options, 0, false).
-%% @spec (Size::integer(), Options::term()) -> array()
%% @doc Create a new array according to the given size and options. If
%% `Size' is not a nonnegative integer, the call fails with reason
%% `badarg'. By default, the array has fixed size. Note that any size
@@ -245,7 +243,7 @@ new(Options) ->
%%
%% @see new/1
--spec new(non_neg_integer(), array_opts()) -> array().
+-spec new(Size :: non_neg_integer(), Options :: array_opts()) -> array().
new(Size, Options) when is_integer(Size), Size >= 0 ->
new_0(Options, Size, true);
@@ -293,13 +291,12 @@ find_max(_I, M) ->
M.
-%% @spec (X::term()) -> boolean()
%% @doc Returns `true' if `X' appears to be an array, otherwise `false'.
%% Note that the check is only shallow; there is no guarantee that `X'
%% is a well-formed array representation even if this function returns
%% `true'.
--spec is_array(term()) -> boolean().
+-spec is_array(X :: term()) -> boolean().
is_array(#array{size = Size, max = Max})
when is_integer(Size), is_integer(Max) ->
@@ -308,25 +305,23 @@ is_array(_) ->
false.
-%% @spec (array()) -> integer()
%% @doc Get the number of entries in the array. Entries are numbered
%% from 0 to `size(Array)-1'; hence, this is also the index of the first
%% entry that is guaranteed to not have been previously set.
%% @see set/3
%% @see sparse_size/1
--spec size(array()) -> non_neg_integer().
+-spec size(Array :: array()) -> non_neg_integer().
size(#array{size = N}) -> N;
size(_) -> erlang:error(badarg).
-%% @spec (array()) -> term()
%% @doc Get the value used for uninitialized entries.
%%
%% @see new/2
--spec default(array()) -> term().
+-spec default(Array :: array()) -> term().
default(#array{default = D}) -> D;
default(_) -> erlang:error(badarg).
@@ -405,23 +400,21 @@ new_test_() ->
-endif.
-%% @spec (array()) -> array()
%% @doc Fix the size of the array. This prevents it from growing
%% automatically upon insertion; see also {@link set/3}.
%% @see relax/1
--spec fix(array()) -> array().
+-spec fix(Array :: array()) -> array().
fix(#array{}=A) ->
A#array{max = 0}.
-%% @spec (array()) -> boolean()
%% @doc Check if the array has fixed size.
%% Returns `true' if the array is fixed, otherwise `false'.
%% @see fix/1
--spec is_fix(array()) -> boolean().
+-spec is_fix(Array :: array()) -> boolean().
is_fix(#array{max = 0}) -> true;
is_fix(#array{}) -> false.
@@ -455,12 +448,11 @@ fix_test_() ->
-endif.
-%% @spec (array()) -> array()
%% @doc Make the array resizable. (Reverses the effects of {@link
%% fix/1}.)
%% @see fix/1
--spec relax(array()) -> array().
+-spec relax(Array :: array()) -> array().
relax(#array{size = N}=A) ->
A#array{max = find_max(N-1, ?LEAFSIZE)}.
@@ -481,12 +473,11 @@ relax_test_() ->
-endif.
-%% @spec (integer(), array()) -> array()
%% @doc Change the size of the array. If `Size' is not a nonnegative
%% integer, the call fails with reason `badarg'. If the given array has
%% fixed size, the resulting array will also have fixed size.
--spec resize(non_neg_integer(), array()) -> array().
+-spec resize(Size :: non_neg_integer(), Array :: array()) -> array().
resize(Size, #array{size = N, max = M, elements = E}=A)
when is_integer(Size), Size >= 0 ->
@@ -510,8 +501,6 @@ resize(_Size, _) ->
erlang:error(badarg).
-%% @spec (array()) -> array()
-
%% @doc Change the size of the array to that reported by {@link
%% sparse_size/1}. If the given array has fixed size, the resulting
%% array will also have fixed size.
@@ -519,7 +508,7 @@ resize(_Size, _) ->
%% @see resize/2
%% @see sparse_size/1
--spec resize(array()) -> array().
+-spec resize(Array :: array()) -> array().
resize(Array) ->
resize(sparse_size(Array), Array).
@@ -559,7 +548,6 @@ resize_test_() ->
-endif.
-%% @spec (integer(), term(), array()) -> array()
%% @doc Set entry `I' of the array to `Value'. If `I' is not a
%% nonnegative integer, or if the array has fixed size and `I' is larger
%% than the maximum index, the call fails with reason `badarg'.
@@ -570,7 +558,7 @@ resize_test_() ->
%% @see get/2
%% @see reset/2
--spec set(array_indx(), term(), array()) -> array().
+-spec set(I :: array_indx(), Value :: term(), Array :: array()) -> array().
set(I, Value, #array{size = N, max = M, default = D, elements = E}=A)
when is_integer(I), I >= 0 ->
@@ -624,7 +612,6 @@ expand(I, _S, X, D) ->
setelement(I+1, ?NEW_LEAF(D), X).
-%% @spec (integer(), array()) -> term()
%% @doc Get the value of entry `I'. If `I' is not a nonnegative
%% integer, or if the array has fixed size and `I' is larger than the
%% maximum index, the call fails with reason `badarg'.
@@ -634,7 +621,7 @@ expand(I, _S, X, D) ->
%% @see set/3
--spec get(array_indx(), array()) -> term().
+-spec get(I :: array_indx(), Array :: array()) -> term().
get(I, #array{size = N, max = M, elements = E, default = D})
when is_integer(I), I >= 0 ->
@@ -660,7 +647,6 @@ get_1(I, E, _D) ->
element(I+1, E).
-%% @spec (integer(), array()) -> array()
%% @doc Reset entry `I' to the default value for the array.
%% If the value of entry `I' is the default value the array will be
%% returned unchanged. Reset will never change size of the array.
@@ -675,7 +661,7 @@ get_1(I, E, _D) ->
%% TODO: a reset_range function
--spec reset(array_indx(), array()) -> array().
+-spec reset(I :: array_indx(), Array :: array()) -> array().
reset(I, #array{size = N, max = M, default = D, elements = E}=A)
when is_integer(I), I >= 0 ->
@@ -756,13 +742,12 @@ set_get_test_() ->
-endif.
-%% @spec (array()) -> list()
%% @doc Converts the array to a list.
%%
%% @see from_list/2
%% @see sparse_to_list/1
--spec to_list(array()) -> list().
+-spec to_list(Array :: array()) -> list().
to_list(#array{size = 0}) ->
[];
@@ -831,12 +816,11 @@ to_list_test_() ->
-endif.
-%% @spec (array()) -> list()
%% @doc Converts the array to a list, skipping default-valued entries.
%%
%% @see to_list/1
--spec sparse_to_list(array()) -> list().
+-spec sparse_to_list(Array :: array()) -> list().
sparse_to_list(#array{size = 0}) ->
[];
@@ -901,15 +885,13 @@ sparse_to_list_test_() ->
-endif.
-%% @spec (list()) -> array()
%% @equiv from_list(List, undefined)
--spec from_list(list()) -> array().
+-spec from_list(List :: list()) -> array().
from_list(List) ->
from_list(List, undefined).
-%% @spec (list(), term()) -> array()
%% @doc Convert a list to an extendible array. `Default' is used as the value
%% for uninitialized entries of the array. If `List' is not a proper list,
%% the call fails with reason `badarg'.
@@ -917,7 +899,7 @@ from_list(List) ->
%% @see new/2
%% @see to_list/1
--spec from_list(list(), term()) -> array().
+-spec from_list(List :: list(), Default :: term()) -> array().
from_list([], Default) ->
new({default,Default});
@@ -1011,13 +993,12 @@ from_list_test_() ->
-endif.
-%% @spec (array()) -> [{Index::integer(), Value::term()}]
%% @doc Convert the array to an ordered list of pairs `{Index, Value}'.
%%
%% @see from_orddict/2
%% @see sparse_to_orddict/1
--spec to_orddict(array()) -> indx_pairs().
+-spec to_orddict(Array :: array()) -> indx_pairs().
to_orddict(#array{size = 0}) ->
[];
@@ -1104,13 +1085,12 @@ to_orddict_test_() ->
-endif.
-%% @spec (array()) -> [{Index::integer(), Value::term()}]
%% @doc Convert the array to an ordered list of pairs `{Index, Value}',
%% skipping default-valued entries.
%%
%% @see to_orddict/1
--spec sparse_to_orddict(array()) -> indx_pairs().
+-spec sparse_to_orddict(Array :: array()) -> indx_pairs().
sparse_to_orddict(#array{size = 0}) ->
[];
@@ -1188,15 +1168,13 @@ sparse_to_orddict_test_() ->
-endif.
-%% @spec (list()) -> array()
%% @equiv from_orddict(Orddict, undefined)
--spec from_orddict(indx_pairs()) -> array().
+-spec from_orddict(Orddict :: indx_pairs()) -> array().
from_orddict(Orddict) ->
from_orddict(Orddict, undefined).
-%% @spec (list(), term()) -> array()
%% @doc Convert an ordered list of pairs `{Index, Value}' to a
%% corresponding extendible array. `Default' is used as the value for
%% uninitialized entries of the array. If `List' is not a proper,
@@ -1206,7 +1184,7 @@ from_orddict(Orddict) ->
%% @see new/2
%% @see to_orddict/1
--spec from_orddict(indx_pairs(), term()) -> array().
+-spec from_orddict(Orddict :: indx_pairs(), Default :: term()) -> array().
from_orddict([], Default) ->
new({default,Default});
@@ -1392,7 +1370,6 @@ from_orddict_test_() ->
-endif.
-%% @spec (Function, array()) -> array()
%% Function = (Index::integer(), Value::term()) -> term()
%% @doc Map the given function onto each element of the array. The
%% elements are visited in order from the lowest index to the highest.
@@ -1402,7 +1379,8 @@ from_orddict_test_() ->
%% @see foldr/3
%% @see sparse_map/2
--spec map(fun((array_indx(), _) -> _), array()) -> array().
+-spec map(Function, Array :: array()) -> array() when
+ Function :: fun((Index :: array_indx(), Value :: _) -> _).
map(Function, Array=#array{size = N, elements = E, default = D})
when is_function(Function, 2) ->
@@ -1485,7 +1463,6 @@ map_test_() ->
-endif.
-%% @spec (Function, array()) -> array()
%% Function = (Index::integer(), Value::term()) -> term()
%% @doc Map the given function onto each element of the array, skipping
%% default-valued entries. The elements are visited in order from the
@@ -1494,7 +1471,8 @@ map_test_() ->
%%
%% @see map/2
--spec sparse_map(fun((array_indx(), _) -> _), array()) -> array().
+-spec sparse_map(Function, Array :: array()) -> array() when
+ Function :: fun((Index :: array_indx(), Value :: _) -> _).
sparse_map(Function, Array=#array{size = N, elements = E, default = D})
when is_function(Function, 2) ->
@@ -1580,9 +1558,6 @@ sparse_map_test_() ->
-endif.
-%% @spec (Function, InitialAcc::term(), array()) -> term()
-%% Function = (Index::integer(), Value::term(), Acc::term()) ->
-%% term()
%% @doc Fold the elements of the array using the given function and
%% initial accumulator value. The elements are visited in order from the
%% lowest index to the highest. If `Function' is not a function, the
@@ -1592,7 +1567,8 @@ sparse_map_test_() ->
%% @see map/2
%% @see sparse_foldl/3
--spec foldl(fun((array_indx(), _, A) -> B), A, array()) -> B.
+-spec foldl(Function, InitialAcc :: A, Array :: array()) -> B when
+ Function :: fun((Index :: array_indx(), Value :: _, Acc :: A) -> B).
foldl(Function, A, #array{size = N, elements = E, default = D})
when is_function(Function, 3) ->
@@ -1656,9 +1632,6 @@ foldl_test_() ->
-endif.
-%% @spec (Function, InitialAcc::term(), array()) -> term()
-%% Function = (Index::integer(), Value::term(), Acc::term()) ->
-%% term()
%% @doc Fold the elements of the array using the given function and
%% initial accumulator value, skipping default-valued entries. The
%% elements are visited in order from the lowest index to the highest.
@@ -1667,7 +1640,8 @@ foldl_test_() ->
%% @see foldl/3
%% @see sparse_foldr/3
--spec sparse_foldl(fun((array_indx(), _, A) -> B), A, array()) -> B.
+-spec sparse_foldl(Function, InitialAcc :: A, Array :: array()) -> B when
+ Function :: fun((Index :: array_indx(), Value :: _, Acc :: A) -> B).
sparse_foldl(Function, A, #array{size = N, elements = E, default = D})
when is_function(Function, 3) ->
@@ -1735,9 +1709,6 @@ sparse_foldl_test_() ->
-endif.
-%% @spec (Function, InitialAcc::term(), array()) -> term()
-%% Function = (Index::integer(), Value::term(), Acc::term()) ->
-%% term()
%% @doc Fold the elements of the array right-to-left using the given
%% function and initial accumulator value. The elements are visited in
%% order from the highest index to the lowest. If `Function' is not a
@@ -1746,7 +1717,8 @@ sparse_foldl_test_() ->
%% @see foldl/3
%% @see map/2
--spec foldr(fun((array_indx(), _, A) -> B), A, array()) -> B.
+-spec foldr(Function, InitialAcc :: A, Array :: array()) -> B when
+ Function :: fun((Index :: array_indx(), Value :: _, Acc :: A) -> B).
foldr(Function, A, #array{size = N, elements = E, default = D})
when is_function(Function, 3) ->
@@ -1815,9 +1787,6 @@ foldr_test_() ->
-endif.
-%% @spec (Function, InitialAcc::term(), array()) -> term()
-%% Function = (Index::integer(), Value::term(), Acc::term()) ->
-%% term()
%% @doc Fold the elements of the array right-to-left using the given
%% function and initial accumulator value, skipping default-valued
%% entries. The elements are visited in order from the highest index to
@@ -1827,7 +1796,8 @@ foldr_test_() ->
%% @see foldr/3
%% @see sparse_foldl/3
--spec sparse_foldr(fun((array_indx(), _, A) -> B), A, array()) -> B.
+-spec sparse_foldr(Function, InitialAcc :: A, Array :: array()) -> B when
+ Function :: fun((Index :: array_indx(), Value :: _, Acc :: A) -> B).
sparse_foldr(Function, A, #array{size = N, elements = E, default = D})
when is_function(Function, 3) ->
@@ -1870,7 +1840,6 @@ sparse_foldr_3(I, T, Ix, A, F, D) ->
end.
-%% @spec (array()) -> integer()
%% @doc Get the number of entries in the array up until the last
%% non-default valued entry. In other words, returns `I+1' if `I' is the
%% last non-default valued entry in the array, or zero if no such entry
@@ -1878,7 +1847,7 @@ sparse_foldr_3(I, T, Ix, A, F, D) ->
%% @see size/1
%% @see resize/1
--spec sparse_size(array()) -> non_neg_integer().
+-spec sparse_size(Array :: array()) -> non_neg_integer().
sparse_size(A) ->
F = fun (I, _V, _A) -> throw({value, I}) end,
diff --git a/lib/stdlib/src/base64.erl b/lib/stdlib/src/base64.erl
index a14a72ac6d..5d800e87b8 100644
--- a/lib/stdlib/src/base64.erl
+++ b/lib/stdlib/src/base64.erl
@@ -38,7 +38,9 @@
%% Description: Encodes a plain ASCII string (or binary) into base64.
%%-------------------------------------------------------------------------
--spec encode_to_string(string() | binary()) -> ascii_string().
+-spec encode_to_string(Data) -> Base64String when
+ Data :: string() | binary(),
+ Base64String :: ascii_string().
encode_to_string(Bin) when is_binary(Bin) ->
encode_to_string(binary_to_list(Bin));
@@ -53,7 +55,9 @@ encode_to_string(List) when is_list(List) ->
%% Description: Encodes a plain ASCII string (or binary) into base64.
%%-------------------------------------------------------------------------
--spec encode(string() | binary()) -> binary().
+-spec encode(Data) -> Base64 when
+ Data :: string() | binary(),
+ Base64 :: binary().
encode(Bin) when is_binary(Bin) ->
encode_binary(Bin);
@@ -102,14 +106,18 @@ encode_binary(Bin) ->
%% whereas decode crashes if an illegal character is found
%%-------------------------------------------------------------------------
--spec decode(string() | binary()) -> binary().
+-spec decode(Base64) -> Data when
+ Base64 :: string() | binary(),
+ Data :: binary().
decode(Bin) when is_binary(Bin) ->
decode_binary(<<>>, Bin);
decode(List) when is_list(List) ->
list_to_binary(decode_l(List)).
--spec mime_decode(string() | binary()) -> binary().
+-spec mime_decode(Base64) -> Data when
+ Base64 :: string() | binary(),
+ Data :: binary().
mime_decode(Bin) when is_binary(Bin) ->
mime_decode_binary(<<>>, Bin);
@@ -139,14 +147,18 @@ mime_decode_l(List) ->
%% whereas decode crashes if an illegal character is found
%%-------------------------------------------------------------------------
--spec decode_to_string(string() | binary()) -> string().
+-spec decode_to_string(Base64) -> DataString when
+ Base64 :: string() | binary(),
+ DataString :: string().
decode_to_string(Bin) when is_binary(Bin) ->
decode_to_string(binary_to_list(Bin));
decode_to_string(List) when is_list(List) ->
decode_l(List).
--spec mime_decode_to_string(string() | binary()) -> string().
+-spec mime_decode_to_string(Base64) -> DataString when
+ Base64 :: string() | binary(),
+ DataString :: string().
mime_decode_to_string(Bin) when is_binary(Bin) ->
mime_decode_to_string(binary_to_list(Bin));
diff --git a/lib/stdlib/src/beam_lib.erl b/lib/stdlib/src/beam_lib.erl
index 74d4ad3da7..d9c645d787 100644
--- a/lib/stdlib/src/beam_lib.erl
+++ b/lib/stdlib/src/beam_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -54,13 +54,9 @@
-type beam() :: module() | file:filename() | binary().
-%% XXX: THE FOLLOWING SHOULD BE IMPORTED FROM SOMEWHERE ELSE
--type forms() :: term().
+-type forms() :: [erl_parse:abstract_form()].
--type abst_vsn() :: atom().
--type abst_code() :: {abst_vsn(), forms()} | 'no_abstract_code'.
--type attribute() :: atom().
--type attrvalue() :: term().
+-type abst_code() :: {AbstVersion :: atom(), forms()} | 'no_abstract_code'.
-type dataB() :: binary().
-type index() :: non_neg_integer().
-type label() :: integer().
@@ -74,9 +70,9 @@
| 'atoms'.
-type chunkref() :: chunkname() | chunkid().
--type attrib_entry() :: {attribute(), [attrvalue()]}.
--type compinfo_entry() :: {atom(), term()}.
--type labeled_entry() :: {atom(), arity(), label()}.
+-type attrib_entry() :: {Attribute :: atom(), [AttributeValue :: term()]}.
+-type compinfo_entry() :: {InfoKey :: atom(), term()}.
+-type labeled_entry() :: {Function :: atom(), arity(), label()}.
-type chunkdata() :: {chunkid(), dataB()}
| {'abstract_code', abst_code()}
@@ -85,20 +81,17 @@
| {'exports', [{atom(), arity()}]}
| {'labeled_exports', [labeled_entry()]}
| {'imports', [mfa()]}
- | {'indexed_imports', [{index(), module(), atom(), arity()}]}
+ | {'indexed_imports', [{index(), module(), Function :: atom(), arity()}]}
| {'locals', [{atom(), arity()}]}
| {'labeled_locals', [labeled_entry()]}
| {'atoms', [{integer(), atom()}]}.
--type info_pair() :: {'file', file:filename()}
- | {'binary', binary()}
- | {'module', module()}
- | {'chunks', [{chunkid(), integer(), integer()}]}.
-
%% Error reasons
-type info_rsn() :: {'chunk_too_big', file:filename(),
- chunkid(), integer(), integer()}
- | {'invalid_beam_file', file:filename(), integer()}
+ chunkid(), ChunkSize :: non_neg_integer(),
+ FileSize :: non_neg_integer()}
+ | {'invalid_beam_file', file:filename(),
+ Position :: non_neg_integer()}
| {'invalid_chunk', file:filename(), chunkid()}
| {'missing_chunk', file:filename(), chunkid()}
| {'not_a_beam_file', file:filename()}
@@ -118,20 +111,34 @@
%% Exported functions
%%
--spec info(beam()) -> [info_pair()] | {'error', 'beam_lib', info_rsn()}.
+-spec info(Beam) -> [InfoPair] | {'error', 'beam_lib', info_rsn()} when
+ Beam :: beam(),
+ InfoPair :: {'file', Filename :: file:filename()}
+ | {'binary', Binary :: binary()}
+ | {'module', Module :: module()}
+ | {'chunks', [{ChunkId :: chunkid(),
+ Pos :: non_neg_integer(),
+ Size :: non_neg_integer()}]}.
info(File) ->
read_info(beam_filename(File)).
--spec chunks(beam(), [chunkref()]) ->
- {'ok', {module(), [chunkdata()]}} | {'error', 'beam_lib', chnk_rsn()}.
+-spec chunks(Beam, ChunkRefs) ->
+ {'ok', {module(), [chunkdata()]}} |
+ {'error', 'beam_lib', chnk_rsn()} when
+ Beam :: beam(),
+ ChunkRefs :: [chunkref()].
chunks(File, Chunks) ->
read_chunk_data(File, Chunks).
--spec chunks(beam(), [chunkref()], ['allow_missing_chunks']) ->
- {'ok', {module(), [{chunkref(), chunkdata() | 'missing_chunk'}]}}
- | {'error', 'beam_lib', chnk_rsn()}.
+-spec chunks(Beam, ChunkRefs, Options) ->
+ {'ok', {module(), [ChunkResult]}} |
+ {'error', 'beam_lib', chnk_rsn()} when
+ Beam :: beam(),
+ ChunkRefs :: [chunkref()],
+ Options :: ['allow_missing_chunks'],
+ ChunkResult :: chunkdata() | {ChunkRef :: chunkref(), 'missing_chunk'}.
chunks(File, Chunks, Options) ->
try read_chunk_data(File, Chunks, Options)
@@ -142,49 +149,65 @@ chunks(File, Chunks, Options) ->
all_chunks(File) ->
read_all_chunks(File).
--spec cmp(beam(), beam()) -> 'ok' | {'error', 'beam_lib', cmp_rsn()}.
+-spec cmp(Beam1, Beam2) -> 'ok' | {'error', 'beam_lib', cmp_rsn()} when
+ Beam1 :: beam(),
+ Beam2 :: beam().
cmp(File1, File2) ->
try cmp_files(File1, File2)
catch Error -> Error end.
--spec cmp_dirs(atom() | file:filename(), atom() | file:filename()) ->
- {[file:filename()], [file:filename()],
- [{file:filename(), file:filename()}]}
- | {'error', 'beam_lib', {'not_a_directory', term()} | info_rsn()}.
+-spec cmp_dirs(Dir1, Dir2) ->
+ {Only1, Only2, Different} | {'error', 'beam_lib', Reason} when
+ Dir1 :: atom() | file:filename(),
+ Dir2 :: atom() | file:filename(),
+ Only1 :: [file:filename()],
+ Only2 :: [file:filename()],
+ Different :: [{Filename1 :: file:filename(), Filename2 :: file:filename()}],
+ Reason :: {'not_a_directory', term()} | info_rsn().
cmp_dirs(Dir1, Dir2) ->
catch compare_dirs(Dir1, Dir2).
--spec diff_dirs(atom() | file:filename(), atom() | file:filename()) ->
- 'ok' | {'error', 'beam_lib', {'not_a_directory', term()} | info_rsn()}.
+-spec diff_dirs(Dir1, Dir2) -> 'ok' | {'error', 'beam_lib', Reason} when
+ Dir1 :: atom() | file:filename(),
+ Dir2 :: atom() | file:filename(),
+ Reason :: {'not_a_directory', term()} | info_rsn().
diff_dirs(Dir1, Dir2) ->
catch diff_directories(Dir1, Dir2).
--spec strip(beam()) ->
- {'ok', {module(), beam()}} | {'error', 'beam_lib', info_rsn()}.
+-spec strip(Beam1) ->
+ {'ok', {module(), Beam2}} | {'error', 'beam_lib', info_rsn()} when
+ Beam1 :: beam(),
+ Beam2 :: beam().
strip(FileName) ->
try strip_file(FileName)
catch Error -> Error end.
--spec strip_files([beam()]) ->
- {'ok', [{module(), beam()}]} | {'error', 'beam_lib', info_rsn()}.
+-spec strip_files(Files) ->
+ {'ok', [{module(), Beam}]} | {'error', 'beam_lib', info_rsn()} when
+ Files :: [beam()],
+ Beam :: beam().
strip_files(Files) when is_list(Files) ->
try strip_fils(Files)
catch Error -> Error end.
--spec strip_release(atom() | file:filename()) ->
+-spec strip_release(Dir) ->
{'ok', [{module(), file:filename()}]}
- | {'error', 'beam_lib', {'not_a_directory', term()} | info_rsn()}.
+ | {'error', 'beam_lib', Reason} when
+ Dir :: atom() | file:filename(),
+ Reason :: {'not_a_directory', term()} | info_rsn().
strip_release(Root) ->
catch strip_rel(Root).
--spec version(beam()) ->
- {'ok', {module(), [term()]}} | {'error', 'beam_lib', chnk_rsn()}.
+-spec version(Beam) ->
+ {'ok', {module(), [Version :: term()]}} |
+ {'error', 'beam_lib', chnk_rsn()} when
+ Beam :: beam().
version(File) ->
case catch read_chunk_data(File, [attributes]) of
@@ -195,8 +218,10 @@ version(File) ->
Error
end.
--spec md5(beam()) ->
- {'ok', {module(), binary()}} | {'error', 'beam_lib', chnk_rsn()}.
+-spec md5(Beam) ->
+ {'ok', {module(), MD5}} | {'error', 'beam_lib', chnk_rsn()} when
+ Beam :: beam(),
+ MD5 :: binary().
md5(File) ->
case catch read_significant_chunks(File) of
@@ -207,7 +232,8 @@ md5(File) ->
Error
end.
--spec format_error(term()) -> [char() | string()].
+-spec format_error(Reason) -> io_lib:chars() when
+ Reason :: term().
format_error({error, Error}) ->
format_error(Error);
@@ -260,12 +286,15 @@ format_error(E) ->
| {'debug_info', mode(), module(), file:filename()}.
-type crypto_fun() :: fun((crypto_fun_arg()) -> term()).
--spec crypto_key_fun(crypto_fun()) -> 'ok' | {'error', term()}.
+-spec crypto_key_fun(CryptoKeyFun) -> 'ok' | {'error', Reason} when
+ CryptoKeyFun :: crypto_fun(),
+ Reason :: badfun | exists | term().
crypto_key_fun(F) ->
call_crypto_server({crypto_key_fun, F}).
--spec clear_crypto_key_fun() -> 'undefined' | {'ok', term()}.
+-spec clear_crypto_key_fun() -> 'undefined' | {'ok', Result} when
+ Result :: 'undefined' | term().
clear_crypto_key_fun() ->
call_crypto_server(clear_crypto_key_fun).
diff --git a/lib/stdlib/src/binary.erl b/lib/stdlib/src/binary.erl
index f6489788b2..cb1e12ae46 100644
--- a/lib/stdlib/src/binary.erl
+++ b/lib/stdlib/src/binary.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -38,11 +38,28 @@
%% Implemented in this module:
-export([split/2,split/3,replace/3,replace/4]).
+-opaque cp() :: tuple().
+-type part() :: {Start :: non_neg_integer(), Length :: integer()}.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% split
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+-spec split(Subject, Pattern) -> Parts when
+ Subject :: binary(),
+ Pattern :: binary() | [binary()] | cp(),
+ Parts :: [binary()].
+
split(H,N) ->
split(H,N,[]).
+
+-spec split(Subject, Pattern, Options) -> Parts when
+ Subject :: binary(),
+ Pattern :: binary() | [binary()] | cp(),
+ Options :: [Option],
+ Option :: {scope, part()} | trim | global,
+ Parts :: [binary()].
+
split(Haystack,Needles,Options) ->
try
{Part,Global,Trim} = get_opts_split(Options,{no,false,false}),
@@ -89,8 +106,26 @@ do_split(H,[{A,B}|T],N,Trim) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% replace
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+-spec replace(Subject, Pattern, Replacement) -> Result when
+ Subject :: binary(),
+ Pattern :: binary() | [ binary() ] | cp(),
+ Replacement :: binary(),
+ Result :: binary().
+
replace(H,N,R) ->
replace(H,N,R,[]).
+
+-spec replace(Subject, Pattern, Replacement, Options) -> Result when
+ Subject :: binary(),
+ Pattern :: binary() | [ binary() ] | cp(),
+ Replacement :: binary(),
+ Options :: [Option],
+ Option :: global | {scope, part()} | {insert_replaced, InsPos},
+ InsPos :: OnePos | [ OnePos ],
+ OnePos :: non_neg_integer(),
+ Result :: binary().
+
replace(Haystack,Needles,Replacement,Options) ->
try
true = is_binary(Replacement), % Make badarg instead of function clause
diff --git a/lib/stdlib/src/c.erl b/lib/stdlib/src/c.erl
index 235ea939a8..febfdd6285 100644
--- a/lib/stdlib/src/c.erl
+++ b/lib/stdlib/src/c.erl
@@ -71,11 +71,16 @@ help() ->
%% c(FileName)
%% Compile a file/module.
--spec c(file:name()) -> {'ok', module()} | 'error'.
+-spec c(File) -> {'ok', Module} | 'error' when
+ File :: file:name(),
+ Module :: module().
c(File) -> c(File, []).
--spec c(file:name(), [compile:option()]) -> {'ok', module()} | 'error'.
+-spec c(File, Options) -> {'ok', Module} | 'error' when
+ File :: file:name(),
+ Options :: [compile:option()],
+ Module :: module().
c(File, Opts0) when is_list(Opts0) ->
Opts = [report_errors,report_warnings|Opts0],
@@ -140,7 +145,8 @@ check_load(_, Mod) -> {ok, Mod}.
%% with constant c2 defined, c1=v1 (v1 must be a term!), include dir
%% IDir, outdir ODir.
--spec lc([erl_compile:cmd_line_arg()]) -> 'ok' | 'error'.
+-spec lc(Files) -> 'ok' | 'error' when
+ Files :: [File :: erl_compile:cmd_line_arg()].
lc(Args) ->
case catch split(Args, [], []) of
@@ -205,12 +211,17 @@ make_term(Str) ->
throw(error)
end.
--spec nc(file:name()) -> {'ok', module()} | 'error'.
+-spec nc(File) -> {'ok', Module} | 'error' when
+ File :: file:name(),
+ Module :: module().
nc(File) -> nc(File, []).
--spec nc(file:name(), [compile:option()] | compile:option()) ->
- {'ok', module} | 'error'.
+-spec nc(File, Options) -> {'ok', Module} | 'error' when
+ File :: file:name(),
+ Options :: [Option] | Option,
+ Option:: compile:option(),
+ Module :: module().
nc(File, Opts0) when is_list(Opts0) ->
Opts = Opts0 ++ [report_errors, report_warnings],
@@ -234,14 +245,17 @@ nc(File, Opt) when is_atom(Opt) ->
%% l(Mod)
%% Reload module Mod from file of same name
--spec l(module()) -> code:load_ret().
+-spec l(Module) -> code:load_ret() when
+ Module :: module().
l(Mod) ->
code:purge(Mod),
code:load_file(Mod).
%% Network version of l/1
-%%-spec nl(module()) ->
+-spec nl(Module) -> abcast | error when
+ Module :: module().
+
nl(Mod) ->
case code:get_object_code(Mod) of
{_Module, Bin, Fname} ->
@@ -396,15 +410,20 @@ fetch(Key, Info) ->
false -> 0
end.
--spec pid(non_neg_integer(), non_neg_integer(), non_neg_integer()) -> pid().
+-spec pid(X, Y, Z) -> pid() when
+ X :: non_neg_integer(),
+ Y :: non_neg_integer(),
+ Z :: non_neg_integer().
pid(X, Y, Z) ->
list_to_pid("<" ++ integer_to_list(X) ++ "." ++
integer_to_list(Y) ++ "." ++
integer_to_list(Z) ++ ">").
--spec i(non_neg_integer(), non_neg_integer(), non_neg_integer()) ->
- [{atom(), term()}].
+-spec i(X, Y, Z) -> [{atom(), term()}] when
+ X :: non_neg_integer(),
+ Y :: non_neg_integer(),
+ Z :: non_neg_integer().
i(X, Y, Z) -> pinfo(pid(X, Y, Z)).
@@ -413,7 +432,8 @@ i(X, Y, Z) -> pinfo(pid(X, Y, Z)).
q() ->
init:stop().
--spec bt(pid()) -> 'ok' | 'undefined'.
+-spec bt(Pid) -> 'ok' | 'undefined' when
+ Pid :: pid().
bt(Pid) ->
case catch erlang:process_display(Pid, backtrace) of
@@ -476,7 +496,8 @@ bi(I) ->
%%
%% Short and nice form of module info
%%
--spec m(module()) -> 'ok'.
+-spec m(Module) -> 'ok' when
+ Module :: module().
m(M) ->
L = M:module_info(),
@@ -664,7 +685,8 @@ pwd() ->
ok = io:format("Cannot determine current directory\n")
end.
--spec cd(file:name()) -> 'ok'.
+-spec cd(Dir) -> 'ok' when
+ Dir :: file:name().
cd(Dir) ->
file:set_cwd(Dir),
@@ -679,7 +701,8 @@ cd(Dir) ->
ls() ->
ls(".").
--spec ls(file:name()) -> 'ok'.
+-spec ls(Dir) -> 'ok' when
+ Dir :: file:name().
ls(Dir) ->
case file:list_dir(Dir) of
@@ -729,12 +752,19 @@ w(X) ->
%% memory/[0,1]
%%
--spec memory() -> [{atom(), non_neg_integer()}].
+-spec memory() -> [{Type, Size}] when
+ Type :: atom(),
+ Size :: non_neg_integer().
memory() -> erlang:memory().
--spec memory(atom()) -> non_neg_integer()
- ; ([atom()]) -> [{atom(), non_neg_integer()}].
+-spec memory(Type) -> Size when
+ Type :: atom(),
+ Size :: non_neg_integer()
+ ; (Types) -> [{Type, Size}] when
+ Types :: [Type],
+ Type :: atom(),
+ Size :: non_neg_integer().
memory(TypeSpec) -> erlang:memory(TypeSpec).
diff --git a/lib/stdlib/src/calendar.erl b/lib/stdlib/src/calendar.erl
index 33725d999c..8d1071209e 100644
--- a/lib/stdlib/src/calendar.erl
+++ b/lib/stdlib/src/calendar.erl
@@ -63,6 +63,8 @@
%% Types
%%----------------------------------------------------------------------
+-export_type([t_now/0]).
+
-type year() :: non_neg_integer().
-type year1970() :: 1970..10000. % should probably be 1970..
-type month() :: 1..12.
@@ -74,7 +76,9 @@
-type ldom() :: 28 | 29 | 30 | 31. % last day of month
-type weeknum() :: 1..53.
--type t_now() :: {non_neg_integer(),non_neg_integer(),non_neg_integer()}.
+-type t_now() :: {MegaSecs :: non_neg_integer(),
+ Secs :: non_neg_integer(),
+ MicroSecs :: non_neg_integer()}.
-type t_date() :: {year(),month(),day()}.
-type t_time() :: {hour(),minute(),second()}.
@@ -106,7 +110,11 @@
%% January 1st.
%%
%% df/2 catches the case Year<0
--spec date_to_gregorian_days(year(),month(),day()) -> non_neg_integer().
+-spec date_to_gregorian_days(Year, Month, Day) -> Days when
+ Year :: year(),
+ Month :: month(),
+ Day :: day(),
+ Days :: non_neg_integer().
date_to_gregorian_days(Year, Month, Day) when is_integer(Day), Day > 0 ->
Last = last_day_of_the_month(Year, Month),
if
@@ -114,7 +122,9 @@ date_to_gregorian_days(Year, Month, Day) when is_integer(Day), Day > 0 ->
dy(Year) + dm(Month) + df(Year, Month) + Day - 1
end.
--spec date_to_gregorian_days(t_date()) -> non_neg_integer().
+-spec date_to_gregorian_days(Date) -> Days when
+ Date :: t_date(),
+ Days :: non_neg_integer().
date_to_gregorian_days({Year, Month, Day}) ->
date_to_gregorian_days(Year, Month, Day).
@@ -124,7 +134,9 @@ date_to_gregorian_days({Year, Month, Day}) ->
%% Computes the total number of seconds starting from year 0,
%% January 1st.
%%
--spec datetime_to_gregorian_seconds(t_datetime()) -> non_neg_integer().
+-spec datetime_to_gregorian_seconds(DateTime) -> Seconds when
+ DateTime :: t_datetime(),
+ Seconds :: non_neg_integer().
datetime_to_gregorian_seconds({Date, Time}) ->
?SECONDS_PER_DAY*date_to_gregorian_days(Date) +
time_to_seconds(Time).
@@ -135,18 +147,23 @@ datetime_to_gregorian_seconds({Date, Time}) ->
%%
%% Returns: 1 | .. | 7. Monday = 1, Tuesday = 2, ..., Sunday = 7.
%%
--spec day_of_the_week(year(), month(), day()) -> daynum().
+-spec day_of_the_week(Year, Month, Day) -> daynum() when
+ Year :: year(),
+ Month :: month(),
+ Day :: day().
day_of_the_week(Year, Month, Day) ->
(date_to_gregorian_days(Year, Month, Day) + 5) rem 7 + 1.
--spec day_of_the_week(t_date()) -> daynum().
+-spec day_of_the_week(Date) -> daynum() when
+ Date:: t_date().
day_of_the_week({Year, Month, Day}) ->
day_of_the_week(Year, Month, Day).
%% gregorian_days_to_date(Days) = {Year, Month, Day}
%%
--spec gregorian_days_to_date(non_neg_integer()) -> t_date().
+-spec gregorian_days_to_date(Days) -> t_date() when
+ Days :: non_neg_integer().
gregorian_days_to_date(Days) ->
{Year, DayOfYear} = day_to_year(Days),
{Month, DayOfMonth} = year_day_to_date(Year, DayOfYear),
@@ -155,7 +172,8 @@ gregorian_days_to_date(Days) ->
%% gregorian_seconds_to_datetime(Secs)
%%
--spec gregorian_seconds_to_datetime(non_neg_integer()) -> t_datetime().
+-spec gregorian_seconds_to_datetime(Seconds) -> t_datetime() when
+ Seconds :: non_neg_integer().
gregorian_seconds_to_datetime(Secs) when Secs >= 0 ->
Days = Secs div ?SECONDS_PER_DAY,
Rest = Secs rem ?SECONDS_PER_DAY,
@@ -164,7 +182,8 @@ gregorian_seconds_to_datetime(Secs) when Secs >= 0 ->
%% is_leap_year(Year) = true | false
%%
--spec is_leap_year(year()) -> boolean().
+-spec is_leap_year(Year) -> boolean() when
+ Year :: year().
is_leap_year(Y) when is_integer(Y), Y >= 0 ->
is_leap_year1(Y).
@@ -188,7 +207,8 @@ iso_week_number() ->
%%
%% Calculates the iso week number for the given date.
%%
--spec iso_week_number(t_date()) -> t_yearweeknum().
+-spec iso_week_number(Date) -> t_yearweeknum() when
+ Date :: t_date().
iso_week_number({Year, Month, Day}) ->
D = date_to_gregorian_days({Year, Month, Day}),
W01_1_Year = gregorian_days_of_iso_w01_1(Year),
@@ -216,7 +236,10 @@ iso_week_number({Year, Month, Day}) ->
%%
%% Returns the number of days in a month.
%%
--spec last_day_of_the_month(year(), month()) -> ldom().
+-spec last_day_of_the_month(Year, Month) -> LastDay when
+ Year :: year(),
+ Month :: month(),
+ LastDay :: ldom().
last_day_of_the_month(Y, M) when is_integer(Y), Y >= 0 ->
last_day_of_the_month1(Y, M).
@@ -244,7 +267,9 @@ local_time() ->
%% local_time_to_universal_time(DateTime)
%%
--spec local_time_to_universal_time(t_datetime1970()) -> t_datetime1970().
+-spec local_time_to_universal_time(DateTime1) -> DateTime2 when
+ DateTime1 :: t_datetime1970(),
+ DateTime2 :: t_datetime1970().
local_time_to_universal_time(DateTime) ->
erlang:localtime_to_universaltime(DateTime).
@@ -254,7 +279,9 @@ local_time_to_universal_time(DateTime) ->
local_time_to_universal_time(DateTime, IsDst) ->
erlang:localtime_to_universaltime(DateTime, IsDst).
--spec local_time_to_universal_time_dst(t_datetime1970()) -> [t_datetime1970()].
+-spec local_time_to_universal_time_dst(DateTime1) -> [DateTime] when
+ DateTime1 :: t_datetime1970(),
+ DateTime :: t_datetime1970().
local_time_to_universal_time_dst(DateTime) ->
UtDst = erlang:localtime_to_universaltime(DateTime, true),
Ut = erlang:localtime_to_universaltime(DateTime, false),
@@ -282,12 +309,14 @@ local_time_to_universal_time_dst(DateTime) ->
%% = MilliSec = integer()
%% Returns: {date(), time()}, date() = {Y, M, D}, time() = {H, M, S}.
%%
--spec now_to_datetime(t_now()) -> t_datetime1970().
+-spec now_to_datetime(Now) -> t_datetime1970() when
+ Now :: t_now().
now_to_datetime({MSec, Sec, _uSec}) ->
Sec0 = MSec*1000000 + Sec + ?DAYS_FROM_0_TO_1970*?SECONDS_PER_DAY,
gregorian_seconds_to_datetime(Sec0).
--spec now_to_universal_time(t_now()) -> t_datetime1970().
+-spec now_to_universal_time(Now) -> t_datetime1970() when
+ Now :: t_now().
now_to_universal_time(Now) ->
now_to_datetime(Now).
@@ -296,7 +325,8 @@ now_to_universal_time(Now) ->
%%
%% Args: Now = now()
%%
--spec now_to_local_time(t_now()) -> t_datetime1970().
+-spec now_to_local_time(Now) -> t_datetime1970() when
+ Now :: t_now().
now_to_local_time({MSec, Sec, _uSec}) ->
erlang:universaltime_to_localtime(
now_to_universal_time({MSec, Sec, _uSec})).
@@ -305,7 +335,10 @@ now_to_local_time({MSec, Sec, _uSec}) ->
%% seconds_to_daystime(Secs) = {Days, {Hour, Minute, Second}}
%%
--spec seconds_to_daystime(integer()) -> {integer(), t_time()}.
+-spec seconds_to_daystime(Seconds) -> {Days, Time} when
+ Seconds :: integer(),
+ Days :: integer(),
+ Time :: t_time().
seconds_to_daystime(Secs) ->
Days0 = Secs div ?SECONDS_PER_DAY,
Secs0 = Secs rem ?SECONDS_PER_DAY,
@@ -323,7 +356,8 @@ seconds_to_daystime(Secs) ->
%% Wraps.
%%
-type secs_per_day() :: 0..?SECONDS_PER_DAY.
--spec seconds_to_time(secs_per_day()) -> t_time().
+-spec seconds_to_time(Seconds) -> t_time() when
+ Seconds :: secs_per_day().
seconds_to_time(Secs) when Secs >= 0, Secs < ?SECONDS_PER_DAY ->
Secs0 = Secs rem ?SECONDS_PER_DAY,
Hour = Secs0 div ?SECONDS_PER_HOUR,
@@ -340,8 +374,11 @@ seconds_to_time(Secs) when Secs >= 0, Secs < ?SECONDS_PER_DAY ->
%% Date = {Year, Month, Day}, Time = {Hour, Minute, Sec},
%% Year = Month = Day = Hour = Minute = Sec = integer()
%%
--type timediff() :: {integer(), t_time()}.
--spec time_difference(t_datetime(), t_datetime()) -> timediff().
+-spec time_difference(T1, T2) -> {Days, Time} when
+ T1 :: t_datetime(),
+ T2 :: t_datetime(),
+ Days :: integer(),
+ Time :: t_time().
time_difference({{Y1, Mo1, D1}, {H1, Mi1, S1}},
{{Y2, Mo2, D2}, {H2, Mi2, S2}}) ->
Secs = datetime_to_gregorian_seconds({{Y2, Mo2, D2}, {H2, Mi2, S2}}) -
@@ -352,7 +389,8 @@ time_difference({{Y1, Mo1, D1}, {H1, Mi1, S1}},
%%
%% time_to_seconds(Time)
%%
--spec time_to_seconds(t_time()) -> secs_per_day().
+-spec time_to_seconds(Time) -> secs_per_day() when
+ Time :: t_time().
time_to_seconds({H, M, S}) when is_integer(H), is_integer(M), is_integer(S) ->
H * ?SECONDS_PER_HOUR +
M * ?SECONDS_PER_MINUTE + S.
@@ -368,7 +406,8 @@ universal_time() ->
%% universal_time_to_local_time(DateTime)
%%
--spec universal_time_to_local_time(t_datetime()) -> t_datetime().
+-spec universal_time_to_local_time(DateTime) -> t_datetime() when
+ DateTime :: t_datetime1970().
universal_time_to_local_time(DateTime) ->
erlang:universaltime_to_localtime(DateTime).
@@ -376,7 +415,10 @@ universal_time_to_local_time(DateTime) ->
%% valid_date(Year, Month, Day) = true | false
%% valid_date({Year, Month, Day}) = true | false
%%
--spec valid_date(integer(), integer(), integer()) -> boolean().
+-spec valid_date(Year, Month, Day) -> boolean() when
+ Year :: integer(),
+ Month :: integer(),
+ Day :: integer().
valid_date(Y, M, D) when is_integer(Y), is_integer(M), is_integer(D) ->
valid_date1(Y, M, D).
@@ -386,7 +428,8 @@ valid_date1(Y, M, D) when Y >= 0, M > 0, M < 13, D > 0 ->
valid_date1(_, _, _) ->
false.
--spec valid_date({integer(),integer(),integer()}) -> boolean().
+-spec valid_date(Date) -> boolean() when
+ Date :: t_date().
valid_date({Y, M, D}) ->
valid_date(Y, M, D).
diff --git a/lib/stdlib/src/dets.erl b/lib/stdlib/src/dets.erl
index 6c91f1efb7..1b81862940 100644
--- a/lib/stdlib/src/dets.erl
+++ b/lib/stdlib/src/dets.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -97,10 +97,6 @@
-include("dets.hrl").
--type object() :: tuple().
--type pattern() :: atom() | tuple().
--type tab_name() :: atom() | reference().
-
%%% This is the implementation of the mnesia file storage. Each (non
%%% ram-copy) table is maintained in a corresponding .DAT file. The
%%% dat file is organized as a segmented linear hashlist. The head of
@@ -179,6 +175,21 @@
%%-define(PROFILE(C), C).
-define(PROFILE(C), void).
+-type access() :: 'read' | 'read_write'.
+-type auto_save() :: 'infinity' | non_neg_integer().
+-opaque bindings_cont() :: #dets_cont{}.
+-opaque cont() :: #dets_cont{}.
+-type keypos() :: pos_integer().
+-type match_spec() :: ets:match_spec().
+-type object() :: tuple().
+-type no_slots() :: non_neg_integer() | 'default'.
+-opaque object_cont() :: #dets_cont{}.
+-type pattern() :: atom() | tuple().
+-opaque select_cont() :: #dets_cont{}.
+-type tab_name() :: atom() | reference().
+-type type() :: 'bag' | 'duplicate_bag' | 'set'.
+-type version() :: 8 | 9 | 'default'.
+
%%% Some further debug code was added in R12B-1 (stdlib-1.15.1):
%%% - there is a new open_file() option 'debug';
%%% - there is a new OS environment variable 'DETS_DEBUG';
@@ -203,9 +214,13 @@ add_user(Pid, Tab, Args) ->
all() ->
dets_server:all().
--type cont() :: #dets_cont{}.
--spec bchunk(tab_name(), 'start' | cont()) ->
- {cont(), binary() | tuple()} | '$end_of_table' | {'error', term()}.
+-spec bchunk(Name, Continuation) ->
+ {Continuation2, Data} | '$end_of_table' | {'error', Reason} when
+ Name :: tab_name(),
+ Continuation :: 'start' | cont(),
+ Continuation2 :: cont(),
+ Data :: binary() | tuple(),
+ Reason :: term().
bchunk(Tab, start) ->
badarg(treq(Tab, {bchunk_init, Tab}), [Tab, start]);
@@ -214,7 +229,9 @@ bchunk(Tab, #dets_cont{what = bchunk, tab = Tab} = State) ->
bchunk(Tab, Term) ->
erlang:error(badarg, [Tab, Term]).
--spec close(tab_name()) -> 'ok' | {'error', term()}.
+-spec close(Name) -> 'ok' | {'error', Reason} when
+ Name :: tab_name(),
+ Reason :: term().
close(Tab) ->
case dets_server:close(Tab) of
@@ -224,12 +241,17 @@ close(Tab) ->
Reply
end.
--spec delete(tab_name(), term()) -> 'ok' | {'error', term()}.
+-spec delete(Name, Key) -> 'ok' | {'error', Reason} when
+ Name :: tab_name(),
+ Key :: term(),
+ Reason :: term().
delete(Tab, Key) ->
badarg(treq(Tab, {delete_key, [Key]}), [Tab, Key]).
--spec delete_all_objects(tab_name()) -> 'ok' | {'error', term()}.
+-spec delete_all_objects(Name) -> 'ok' | {'error', Reason} when
+ Name :: tab_name(),
+ Reason :: term().
delete_all_objects(Tab) ->
case treq(Tab, delete_all_objects) of
@@ -241,7 +263,10 @@ delete_all_objects(Tab) ->
Reply
end.
--spec delete_object(tab_name(), object()) -> 'ok' | {'error', term()}.
+-spec delete_object(Name, Object) -> 'ok' | {'error', Reason} when
+ Name :: tab_name(),
+ Object :: object(),
+ Reason :: term().
delete_object(Tab, O) ->
badarg(treq(Tab, {delete_object, [O]}), [Tab, O]).
@@ -264,23 +289,42 @@ fsck(Fname, Version) ->
end
end.
--spec first(tab_name()) -> term() | '$end_of_table'.
+-spec first(Name) -> Key | '$end_of_table' when
+ Name :: tab_name(),
+ Key :: term().
first(Tab) ->
badarg_exit(treq(Tab, first), [Tab]).
--spec foldr(fun((object(), Acc) -> Acc), Acc, tab_name()) -> Acc | {'error', term()}.
+-spec foldr(Function, Acc0, Name) -> Acc | {'error', Reason} when
+ Name :: tab_name(),
+ Function :: fun((Object :: object(), AccIn) -> AccOut),
+ Acc0 :: term(),
+ Acc :: term(),
+ AccIn :: term(),
+ AccOut :: term(),
+ Reason :: term().
foldr(Fun, Acc, Tab) ->
foldl(Fun, Acc, Tab).
--spec foldl(fun((object(), Acc) -> Acc), Acc, tab_name()) -> Acc | {'error', term()}.
+-spec foldl(Function, Acc0, Name) -> Acc | {'error', Reason} when
+ Name :: tab_name(),
+ Function :: fun((Object :: object(), AccIn) -> AccOut),
+ Acc0 :: term(),
+ Acc :: term(),
+ AccIn :: term(),
+ AccOut :: term(),
+ Reason :: term().
foldl(Fun, Acc, Tab) ->
Ref = make_ref(),
do_traverse(Fun, Acc, Tab, Ref).
--spec from_ets(tab_name(), ets:tab()) -> 'ok' | {'error', term()}.
+-spec from_ets(Name, EtsTab) -> 'ok' | {'error', Reason} when
+ Name :: tab_name(),
+ EtsTab :: ets:tab(),
+ Reason :: term().
from_ets(DTab, ETab) ->
ets:safe_fixtable(ETab, true),
@@ -304,6 +348,15 @@ from_ets_fun(LC, ETab) ->
{L, from_ets_fun(ets:select(C), ETab)}
end.
+-spec info(Name) -> InfoList | 'undefined' when
+ Name :: tab_name(),
+ InfoList :: [InfoTuple],
+ InfoTuple :: {'file_size', non_neg_integer()}
+ | {'filename', file:name()}
+ | {'keypos', keypos()}
+ | {'size', non_neg_integer()}
+ | {'type', type()}.
+
info(Tab) ->
case catch dets_server:get_pid(Tab) of
{'EXIT', _Reason} ->
@@ -312,6 +365,14 @@ info(Tab) ->
undefined(req(Pid, info))
end.
+-spec info(Name, Item) -> Value | 'undefined' when
+ Name :: tab_name(),
+ Item :: 'access' | 'auto_save' | 'bchunk_format'
+ | 'hash' | 'file_size' | 'filename' | 'keypos' | 'memory'
+ | 'no_keys' | 'no_objects' | 'no_slots' | 'owner' | 'ram_file'
+ | 'safe_fixed' | 'size' | 'type' | 'version',
+ Value :: term().
+
info(Tab, owner) ->
case catch dets_server:get_pid(Tab) of
Pid when is_pid(Pid) ->
@@ -334,9 +395,26 @@ info(Tab, Tag) ->
undefined(req(Pid, {info, Tag}))
end.
+-spec init_table(Name, InitFun) -> ok | {'error', Reason} when
+ Name :: tab_name(),
+ InitFun :: fun((Arg) -> Res),
+ Arg :: read | close,
+ Res :: end_of_input | {[object()], InitFun} | {Data, InitFun} | term(),
+ Reason :: term(),
+ Data :: binary() | tuple().
+
init_table(Tab, InitFun) ->
init_table(Tab, InitFun, []).
+-spec init_table(Name, InitFun, Options) -> ok | {'error', Reason} when
+ Name :: tab_name(),
+ InitFun :: fun((Arg) -> Res),
+ Arg :: read | close,
+ Res :: end_of_input | {[object()], InitFun} | {Data, InitFun} | term(),
+ Options :: [{min_no_slots,no_slots()} | {format,term | bchunk}],
+ Reason :: term(),
+ Data :: binary() | tuple().
+
init_table(Tab, InitFun, Options) when is_function(InitFun) ->
case options(Options, [format, min_no_slots]) of
{badarg,_} ->
@@ -350,11 +428,20 @@ init_table(Tab, InitFun, Options) when is_function(InitFun) ->
init_table(Tab, InitFun, Options) ->
erlang:error(badarg, [Tab, InitFun, Options]).
+-spec insert(Name, Objects) -> 'ok' | {'error', Reason} when
+ Name :: tab_name(),
+ Objects :: object() | [object()],
+ Reason :: term().
+
insert(Tab, Objs) when is_list(Objs) ->
badarg(treq(Tab, {insert, Objs}), [Tab, Objs]);
insert(Tab, Obj) ->
badarg(treq(Tab, {insert, [Obj]}), [Tab, Obj]).
+-spec insert_new(Name, Objects) -> boolean() when
+ Name :: tab_name(),
+ Objects :: object() | [object()].
+
insert_new(Tab, Objs) when is_list(Objs) ->
badarg(treq(Tab, {insert_new, Objs}), [Tab, Objs]);
insert_new(Tab, Obj) ->
@@ -366,9 +453,17 @@ internal_close(Pid) ->
internal_open(Pid, Ref, Args) ->
req(Pid, {internal_open, Ref, Args}).
+-spec is_compatible_bchunk_format(Name, BchunkFormat) -> boolean() when
+ Name :: tab_name(),
+ BchunkFormat :: binary().
+
is_compatible_bchunk_format(Tab, Term) ->
badarg(treq(Tab, {is_compatible_bchunk_format, Term}), [Tab, Term]).
+-spec is_dets_file(Filename) -> boolean() | {'error', Reason} when
+ Filename :: file:name(),
+ Reason :: term().
+
is_dets_file(FileName) ->
case catch read_file_header(FileName, read, false) of
{ok, Fd, FH} ->
@@ -382,6 +477,12 @@ is_dets_file(FileName) ->
Other
end.
+-spec lookup(Name, Key) -> Objects | {'error', Reason} when
+ Name :: tab_name(),
+ Key :: term(),
+ Objects :: [object()],
+ Reason :: term().
+
lookup(Tab, Key) ->
badarg(treq(Tab, {lookup_keys, [Key]}), [Tab, Key]).
@@ -394,19 +495,43 @@ lookup_keys(Tab, Keys) ->
erlang:error(badarg, [Tab, Keys])
end.
+-spec match(Name, Pattern) -> [Match] | {'error', Reason} when
+ Name :: tab_name(),
+ Pattern :: pattern(),
+ Match :: [term()],
+ Reason :: term().
+
match(Tab, Pat) ->
badarg(safe_match(Tab, Pat, bindings), [Tab, Pat]).
+-spec match(Name, Pattern, N) ->
+ {[Match], Continuation} | '$end_of_table' | {'error', Reason} when
+ Name :: tab_name(),
+ Pattern :: pattern(),
+ N :: 'default' | non_neg_integer(),
+ Continuation :: bindings_cont(),
+ Match :: [term()],
+ Reason :: term().
+
match(Tab, Pat, N) ->
badarg(init_chunk_match(Tab, Pat, bindings, N), [Tab, Pat, N]).
+-spec match(Continuation) ->
+ {[Match], Continuation2} | '$end_of_table' | {'error', Reason} when
+ Continuation :: bindings_cont(),
+ Continuation2 :: bindings_cont(),
+ Match :: [term()],
+ Reason :: term().
+
match(State) when State#dets_cont.what =:= bindings ->
badarg(chunk_match(State), [State]);
match(Term) ->
erlang:error(badarg, [Term]).
--spec match_delete(tab_name(), pattern()) ->
- non_neg_integer() | 'ok' | {'error', term()}.
+-spec match_delete(Name, Pattern) -> 'ok' | {'error', Reason} when
+ Name :: tab_name(),
+ Pattern :: pattern(),
+ Reason :: term().
match_delete(Tab, Pat) ->
badarg(match_delete(Tab, Pat, delete), [Tab, Pat]).
@@ -434,23 +559,60 @@ do_match_delete(Tab, _Proc, Error, _What, _N) ->
safe_fixtable(Tab, false),
Error.
+-spec match_object(Name, Pattern) -> Objects | {'error', Reason} when
+ Name :: tab_name(),
+ Pattern :: pattern(),
+ Objects :: [object()],
+ Reason :: term().
+
match_object(Tab, Pat) ->
badarg(safe_match(Tab, Pat, object), [Tab, Pat]).
+-spec match_object(Name, Pattern, N) ->
+ {Objects, Continuation} | '$end_of_table' | {'error', Reason} when
+ Name :: tab_name(),
+ Pattern :: pattern(),
+ N :: 'default' | non_neg_integer(),
+ Continuation :: object_cont(),
+ Objects :: [object()],
+ Reason :: term().
+
match_object(Tab, Pat, N) ->
badarg(init_chunk_match(Tab, Pat, object, N), [Tab, Pat, N]).
+-spec match_object(Continuation) ->
+ {Objects, Continuation2} | '$end_of_table' | {'error', Reason} when
+ Continuation :: object_cont(),
+ Continuation2 :: object_cont(),
+ Objects :: [object()],
+ Reason :: term().
+
match_object(State) when State#dets_cont.what =:= object ->
badarg(chunk_match(State), [State]);
match_object(Term) ->
erlang:error(badarg, [Term]).
+-spec member(Name, Key) -> boolean() | {'error', Reason} when
+ Name :: tab_name(),
+ Key :: term(),
+ Reason :: term().
+
member(Tab, Key) ->
badarg(treq(Tab, {member, Key}), [Tab, Key]).
+-spec next(Name, Key1) -> Key2 | '$end_of_table' when
+ Name :: tab_name(),
+ Key1 :: term(),
+ Key2 :: term().
+
next(Tab, Key) ->
badarg_exit(treq(Tab, {next, Key}), [Tab, Key]).
+-spec open_file(Filename) -> {'ok', Reference} | {'error', Reason} when
+ Filename :: file:name(),
+ Reference :: reference(),
+ Reason :: term().
+
%% Assuming that a file already exists, open it with the
%% parameters as already specified in the file itself.
%% Return a ref leading to the file.
@@ -462,6 +624,22 @@ open_file(File) ->
einval(Reply, [File])
end.
+-spec open_file(Name, Args) -> {'ok', Name} | {'error', Reason} when
+ Name :: tab_name(),
+ Args :: [OpenArg],
+ OpenArg :: {'access', access()}
+ | {'auto_save', auto_save()}
+ | {'estimated_no_objects', non_neg_integer()}
+ | {'file', file:name()}
+ | {'max_no_slots', no_slots()}
+ | {'min_no_slots', no_slots()}
+ | {'keypos', keypos()}
+ | {'ram_file', boolean()}
+ | {'repair', boolean() | 'force'}
+ | {'type', type()}
+ | {'version', version()},
+ Reason :: term().
+
open_file(Tab, Args) when is_list(Args) ->
case catch defaults(Tab, Args) of
OpenArgs when is_record(OpenArgs, open_args) ->
@@ -477,12 +655,21 @@ open_file(Tab, Args) when is_list(Args) ->
open_file(Tab, Arg) ->
open_file(Tab, [Arg]).
+-spec pid2name(Pid) -> {'ok', Name} | 'undefined' when
+ Pid :: pid(),
+ Name :: tab_name().
+
pid2name(Pid) ->
dets_server:pid2name(Pid).
remove_user(Pid, From) ->
req(Pid, {close, From}).
+-spec repair_continuation(Continuation, MatchSpec) -> Continuation2 when
+ Continuation :: select_cont(),
+ Continuation2 :: select_cont(),
+ MatchSpec :: match_spec().
+
repair_continuation(#dets_cont{match_program = B}=Cont, MS)
when is_binary(B) ->
case ets:is_compiled_ms(B) of
@@ -496,25 +683,63 @@ repair_continuation(#dets_cont{}=Cont, _MS) ->
repair_continuation(T, MS) ->
erlang:error(badarg, [T, MS]).
+-spec safe_fixtable(Name, Fix) -> 'ok' when
+ Name :: tab_name(),
+ Fix :: boolean().
+
safe_fixtable(Tab, Bool) when Bool; not Bool ->
badarg(treq(Tab, {safe_fixtable, Bool}), [Tab, Bool]);
safe_fixtable(Tab, Term) ->
erlang:error(badarg, [Tab, Term]).
+-spec select(Name, MatchSpec) -> Selection | {'error', Reason} when
+ Name :: tab_name(),
+ MatchSpec :: match_spec(),
+ Selection :: [term()],
+ Reason :: term().
+
select(Tab, Pat) ->
badarg(safe_match(Tab, Pat, select), [Tab, Pat]).
+-spec select(Name, MatchSpec, N) ->
+ {Selection, Continuation} | '$end_of_table' | {'error', Reason} when
+ Name :: tab_name(),
+ MatchSpec :: match_spec(),
+ N :: 'default' | non_neg_integer(),
+ Continuation :: select_cont(),
+ Selection :: [term()],
+ Reason :: term().
+
select(Tab, Pat, N) ->
badarg(init_chunk_match(Tab, Pat, select, N), [Tab, Pat, N]).
+-spec select(Continuation) ->
+ {Selection, Continuation2} | '$end_of_table' | {'error', Reason} when
+ Continuation :: select_cont(),
+ Continuation2 :: select_cont(),
+ Selection :: [term()],
+ Reason :: term().
+
select(State) when State#dets_cont.what =:= select ->
badarg(chunk_match(State), [State]);
select(Term) ->
erlang:error(badarg, [Term]).
+-spec select_delete(Name, MatchSpec) -> N | {'error', Reason} when
+ Name :: tab_name(),
+ MatchSpec :: match_spec(),
+ N :: non_neg_integer(),
+ Reason :: term().
+
select_delete(Tab, Pat) ->
badarg(match_delete(Tab, Pat, select), [Tab, Pat]).
+-spec slot(Name, I) -> '$end_of_table' | Objects | {'error', Reason} when
+ Name :: tab_name(),
+ I :: non_neg_integer(),
+ Objects :: [object()],
+ Reason :: term().
+
slot(Tab, Slot) when is_integer(Slot), Slot >= 0 ->
badarg(treq(Tab, {slot, Slot}), [Tab, Slot]);
slot(Tab, Term) ->
@@ -529,12 +754,29 @@ stop() ->
istart_link(Server) ->
{ok, proc_lib:spawn_link(dets, init, [self(), Server])}.
+-spec sync(Name) -> 'ok' | {'error', Reason} when
+ Name :: tab_name(),
+ Reason :: term().
+
sync(Tab) ->
badarg(treq(Tab, sync), [Tab]).
+-spec table(Name) -> QueryHandle when
+ Name :: tab_name(),
+ QueryHandle :: qlc:query_handle().
+
table(Tab) ->
table(Tab, []).
+-spec table(Name, Options) -> QueryHandle when
+ Name :: tab_name(),
+ Options :: Option | [Option],
+ Option :: {'n_objects', Limit}
+ | {'traverse', TraverseMethod},
+ Limit :: 'default' | pos_integer(),
+ TraverseMethod :: 'first_next' | 'select' | {'select', match_spec()},
+ QueryHandle :: qlc:query_handle().
+
table(Tab, Opts) ->
case options(Opts, [traverse, n_objects]) of
{badarg,_} ->
@@ -612,6 +854,11 @@ table_info(_Tab, _) ->
%% End of table/2.
+-spec to_ets(Name, EtsTab) -> EtsTab | {'error', Reason} when
+ Name :: tab_name(),
+ EtsTab :: ets:tab(),
+ Reason :: term().
+
to_ets(DTab, ETab) ->
case ets:info(ETab, protection) of
undefined ->
@@ -621,6 +868,16 @@ to_ets(DTab, ETab) ->
foldl(Fun, ETab, DTab)
end.
+-spec traverse(Name, Fun) -> Return | {'error', Reason} when
+ Name :: tab_name(),
+ Fun :: fun((Object) -> FunReturn),
+ FunReturn :: 'continue' | {'continue', Val} | {'done', Value},
+ Val :: term(),
+ Value :: term(),
+ Object :: object(),
+ Return :: [term()],
+ Reason :: term().
+
traverse(Tab, Fun) ->
Ref = make_ref(),
TFun =
@@ -638,6 +895,14 @@ traverse(Tab, Fun) ->
end,
do_traverse(TFun, [], Tab, Ref).
+-spec update_counter(Name, Key, Increment) -> Result when
+ Name :: tab_name(),
+ Key :: term(),
+ Increment :: {Pos, Incr} | Incr,
+ Pos :: integer(),
+ Incr :: integer(),
+ Result :: integer().
+
update_counter(Tab, Key, C) ->
badarg(treq(Tab, {update_counter, Key, C}), [Tab, Key, C]).
diff --git a/lib/stdlib/src/dict.erl b/lib/stdlib/src/dict.erl
index 7e51141098..2e9eba4bfa 100644
--- a/lib/stdlib/src/dict.erl
+++ b/lib/stdlib/src/dict.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -80,7 +80,9 @@ new() ->
Empty = mk_seg(?seg_size),
#dict{empty=Empty,segs={Empty}}.
--spec is_key(term(), dict()) -> boolean().
+-spec is_key(Key, Dict) -> boolean() when
+ Key :: term(),
+ Dict :: dict().
is_key(Key, D) ->
Slot = get_slot(D, Key),
@@ -91,21 +93,29 @@ find_key(K, [?kv(K,_Val)|_]) -> true;
find_key(K, [_|Bkt]) -> find_key(K, Bkt);
find_key(_, []) -> false.
--spec to_list(dict()) -> [{term(), term()}].
+-spec to_list(Dict) -> List when
+ Dict :: dict(),
+ List :: [{Key :: term(), Value :: term()}].
to_list(D) ->
fold(fun (Key, Val, List) -> [{Key,Val}|List] end, [], D).
--spec from_list([{term(), term()}]) -> dict().
+-spec from_list(List) -> Dict when
+ List :: [{Key :: term(), Value :: term()}],
+ Dict :: dict().
from_list(L) ->
lists:foldl(fun ({K,V}, D) -> store(K, V, D) end, new(), L).
--spec size(dict()) -> non_neg_integer().
+-spec size(Dict) -> non_neg_integer() when
+ Dict :: dict().
size(#dict{size=N}) when is_integer(N), N >= 0 -> N.
--spec fetch(term(), dict()) -> term().
+-spec fetch(Key, Dict) -> Value when
+ Key :: term(),
+ Dict :: dict(),
+ Value :: term().
fetch(Key, D) ->
Slot = get_slot(D, Key),
@@ -119,7 +129,10 @@ fetch_val(K, [?kv(K,Val)|_]) -> Val;
fetch_val(K, [_|Bkt]) -> fetch_val(K, Bkt);
fetch_val(_, []) -> throw(badarg).
--spec find(term(), dict()) -> {'ok', term()} | 'error'.
+-spec find(Key, Dict) -> {'ok', Value} | 'error' when
+ Key :: term(),
+ Dict :: dict(),
+ Value :: term().
find(Key, D) ->
Slot = get_slot(D, Key),
@@ -130,12 +143,17 @@ find_val(K, [?kv(K,Val)|_]) -> {ok,Val};
find_val(K, [_|Bkt]) -> find_val(K, Bkt);
find_val(_, []) -> error.
--spec fetch_keys(dict()) -> [term()].
+-spec fetch_keys(Dict) -> Keys when
+ Dict :: dict(),
+ Keys :: [term()].
fetch_keys(D) ->
fold(fun (Key, _Val, Keys) -> [Key|Keys] end, [], D).
--spec erase(term(), dict()) -> dict().
+-spec erase(Key, Dict1) -> Dict2 when
+ Key :: term(),
+ Dict1 :: dict(),
+ Dict2 :: dict().
%% Erase all elements with key Key.
erase(Key, D0) ->
@@ -150,7 +168,11 @@ erase_key(Key, [E|Bkt0]) ->
{[E|Bkt1],Dc};
erase_key(_, []) -> {[],0}.
--spec store(term(), term(), dict()) -> dict().
+-spec store(Key, Value, Dict1) -> Dict2 when
+ Key :: term(),
+ Value :: term(),
+ Dict1 :: dict(),
+ Dict2 :: dict().
store(Key, Val, D0) ->
Slot = get_slot(D0, Key),
@@ -166,7 +188,11 @@ store_bkt_val(Key, New, [Other|Bkt0]) ->
{[Other|Bkt1],Ic};
store_bkt_val(Key, New, []) -> {[?kv(Key,New)],1}.
--spec append(term(), term(), dict()) -> dict().
+-spec append(Key, Value, Dict1) -> Dict2 when
+ Key :: term(),
+ Value :: term(),
+ Dict1 :: dict(),
+ Dict2 :: dict().
append(Key, Val, D0) ->
Slot = get_slot(D0, Key),
@@ -182,7 +208,11 @@ append_bkt(Key, Val, [Other|Bkt0]) ->
{[Other|Bkt1],Ic};
append_bkt(Key, Val, []) -> {[?kv(Key,[Val])],1}.
--spec append_list(term(), [term()], dict()) -> dict().
+-spec append_list(Key, ValList, Dict1) -> Dict2 when
+ Key :: term(),
+ ValList :: [Value :: term()],
+ Dict1 :: dict(),
+ Dict2 :: dict().
append_list(Key, L, D0) ->
Slot = get_slot(D0, Key),
@@ -252,7 +282,11 @@ app_list_bkt(Key, L, []) -> {[?kv(Key,L)],1}.
%% {Bkt1,Dc} = on_key_bkt(Key, F, Bkt0),
%% {[Other|Bkt1],Dc}.
--spec update(term(), fun((term()) -> term()), dict()) -> dict().
+-spec update(Key, Fun, Dict1) -> Dict2 when
+ Key :: term(),
+ Fun :: fun((Value1 :: term()) -> Value2 :: term()),
+ Dict1 :: dict(),
+ Dict2 :: dict().
update(Key, F, D0) ->
Slot = get_slot(D0, Key),
@@ -271,7 +305,12 @@ update_bkt(Key, F, [Other|Bkt0]) ->
update_bkt(_Key, _F, []) ->
throw(badarg).
--spec update(term(), fun((term()) -> term()), term(), dict()) -> dict().
+-spec update(Key, Fun, Initial, Dict1) -> Dict2 when
+ Key :: term(),
+ Initial :: term(),
+ Fun :: fun((Value1 :: term()) -> Value2 :: term()),
+ Dict1 :: dict(),
+ Dict2 :: dict().
update(Key, F, Init, D0) ->
Slot = get_slot(D0, Key),
@@ -286,7 +325,11 @@ update_bkt(Key, F, I, [Other|Bkt0]) ->
{[Other|Bkt1],Ic};
update_bkt(Key, F, I, []) when is_function(F, 1) -> {[?kv(Key,I)],1}.
--spec update_counter(term(), number(), dict()) -> dict().
+-spec update_counter(Key, Increment, Dict1) -> Dict2 when
+ Key :: term(),
+ Increment :: number(),
+ Dict1 :: dict(),
+ Dict2 :: dict().
update_counter(Key, Incr, D0) when is_number(Incr) ->
Slot = get_slot(D0, Key),
@@ -301,20 +344,38 @@ counter_bkt(Key, I, [Other|Bkt0]) ->
{[Other|Bkt1],Ic};
counter_bkt(Key, I, []) -> {[?kv(Key,I)],1}.
--spec fold(fun((term(), term(), term()) -> term()), term(), dict()) -> term().
+-spec fold(Fun, Acc0, Dict) -> Acc1 when
+ Fun :: fun((Key, Value, AccIn) -> AccOut),
+ Key :: term(),
+ Value :: term(),
+ Acc0 :: term(),
+ Acc1 :: term(),
+ AccIn :: term(),
+ AccOut :: term(),
+ Dict :: dict().
%% Fold function Fun over all "bags" in Table and return Accumulator.
fold(F, Acc, D) -> fold_dict(F, Acc, D).
--spec map(fun((term(), term()) -> term()), dict()) -> dict().
+-spec map(Fun, Dict1) -> Dict2 when
+ Fun :: fun((Key :: term(), Value1 :: term()) -> Value2 :: term()),
+ Dict1 :: dict(),
+ Dict2 :: dict().
map(F, D) -> map_dict(F, D).
--spec filter(fun((term(), term()) -> boolean()), dict()) -> dict().
+-spec filter(Pred, Dict1) -> Dict2 when
+ Pred :: fun((Key :: term(), Value :: term()) -> boolean()),
+ Dict1 :: dict(),
+ Dict2 :: dict().
filter(F, D) -> filter_dict(F, D).
--spec merge(fun((term(), term(), term()) -> term()), dict(), dict()) -> dict().
+-spec merge(Fun, Dict1, Dict2) -> Dict3 when
+ Fun :: fun((Key :: term(), Value1 :: term(), Value2 :: term()) -> Value :: term()),
+ Dict1 :: dict(),
+ Dict2 :: dict(),
+ Dict3 :: dict().
merge(F, D1, D2) when D1#dict.size < D2#dict.size ->
fold_dict(fun (K, V1, D) ->
diff --git a/lib/stdlib/src/digraph.erl b/lib/stdlib/src/digraph.erl
index 5edc868a94..e3f87d2c57 100644
--- a/lib/stdlib/src/digraph.erl
+++ b/lib/stdlib/src/digraph.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -53,7 +53,8 @@
-type label() :: term().
-type vertex() :: term().
--type add_edge_err_rsn() :: {'bad_edge', [vertex()]} | {'bad_vertex', vertex()}.
+-type add_edge_err_rsn() :: {'bad_edge', Path :: [vertex()]}
+ | {'bad_vertex', V :: vertex()}.
%%
%% Type is a list of
@@ -70,7 +71,8 @@
new() -> new([]).
--spec new([d_type()]) -> digraph().
+-spec new(Type) -> digraph() when
+ Type :: [d_type()].
new(Type) ->
case check_type(Type, protected, []) of
@@ -113,16 +115,20 @@ set_type([], G) -> G.
%% Data access functions
--spec delete(digraph()) -> 'true'.
+-spec delete(G) -> 'true' when
+ G :: digraph().
delete(G) ->
ets:delete(G#digraph.vtab),
ets:delete(G#digraph.etab),
ets:delete(G#digraph.ntab).
--spec info(digraph()) -> [{'cyclicity', d_cyclicity()} |
- {'memory', non_neg_integer()} |
- {'protection', d_protection()}].
+-spec info(G) -> InfoList when
+ G :: digraph(),
+ InfoList :: [{'cyclicity', Cyclicity :: d_cyclicity()} |
+ {'memory', NoWords :: non_neg_integer()} |
+ {'protection', Protection :: d_protection()}].
+
info(G) ->
VT = G#digraph.vtab,
ET = G#digraph.etab,
@@ -135,32 +141,45 @@ info(G) ->
Memory = ets:info(VT, memory) + ets:info(ET, memory) + ets:info(NT, memory),
[{cyclicity, Cyclicity}, {memory, Memory}, {protection, Protection}].
--spec add_vertex(digraph()) -> vertex().
+-spec add_vertex(G) -> vertex() when
+ G :: digraph().
add_vertex(G) ->
do_add_vertex({new_vertex_id(G), []}, G).
--spec add_vertex(digraph(), vertex()) -> vertex().
+-spec add_vertex(G, V) -> vertex() when
+ G :: digraph(),
+ V :: vertex().
add_vertex(G, V) ->
do_add_vertex({V, []}, G).
--spec add_vertex(digraph(), vertex(), label()) -> vertex().
+-spec add_vertex(G, V, Label) -> vertex() when
+ G :: digraph(),
+ V :: vertex(),
+ Label :: label().
add_vertex(G, V, D) ->
do_add_vertex({V, D}, G).
--spec del_vertex(digraph(), vertex()) -> 'true'.
+-spec del_vertex(G, V) -> 'true' when
+ G :: digraph(),
+ V :: vertex().
del_vertex(G, V) ->
do_del_vertex(V, G).
--spec del_vertices(digraph(), [vertex()]) -> 'true'.
+-spec del_vertices(G, Vertices) -> 'true' when
+ G :: digraph(),
+ Vertices :: [vertex()].
del_vertices(G, Vs) ->
do_del_vertices(Vs, G).
--spec vertex(digraph(), vertex()) -> {vertex(), label()} | 'false'.
+-spec vertex(G, V) -> {V, Label} | 'false' when
+ G :: digraph(),
+ V :: vertex(),
+ Label :: label().
vertex(G, V) ->
case ets:lookup(G#digraph.vtab, V) of
@@ -168,12 +187,15 @@ vertex(G, V) ->
[Vertex] -> Vertex
end.
--spec no_vertices(digraph()) -> non_neg_integer().
+-spec no_vertices(G) -> non_neg_integer() when
+ G :: digraph().
no_vertices(G) ->
ets:info(G#digraph.vtab, size).
--spec vertices(digraph()) -> [vertex()].
+-spec vertices(G) -> Vertices when
+ G :: digraph(),
+ Vertices :: [vertex()].
vertices(G) ->
ets:select(G#digraph.vtab, [{{'$1', '_'}, [], ['$1']}]).
@@ -188,85 +210,125 @@ source_vertices(G) ->
sink_vertices(G) ->
collect_vertices(G, out).
--spec in_degree(digraph(), vertex()) -> non_neg_integer().
+-spec in_degree(G, V) -> non_neg_integer() when
+ G :: digraph(),
+ V :: vertex().
in_degree(G, V) ->
length(ets:lookup(G#digraph.ntab, {in, V})).
--spec in_neighbours(digraph(), vertex()) -> [vertex()].
+-spec in_neighbours(G, V) -> Vertex when
+ G :: digraph(),
+ V :: vertex(),
+ Vertex :: [vertex()].
in_neighbours(G, V) ->
ET = G#digraph.etab,
NT = G#digraph.ntab,
collect_elems(ets:lookup(NT, {in, V}), ET, 2).
--spec in_edges(digraph(), vertex()) -> [edge()].
+-spec in_edges(G, V) -> Edges when
+ G :: digraph(),
+ V :: vertex(),
+ Edges :: [edge()].
in_edges(G, V) ->
ets:select(G#digraph.ntab, [{{{in, V}, '$1'}, [], ['$1']}]).
--spec out_degree(digraph(), vertex()) -> non_neg_integer().
+-spec out_degree(G, V) -> non_neg_integer() when
+ G :: digraph(),
+ V :: vertex().
out_degree(G, V) ->
length(ets:lookup(G#digraph.ntab, {out, V})).
--spec out_neighbours(digraph(), vertex()) -> [vertex()].
+-spec out_neighbours(G, V) -> Vertices when
+ G :: digraph(),
+ V :: vertex(),
+ Vertices :: [vertex()].
out_neighbours(G, V) ->
ET = G#digraph.etab,
NT = G#digraph.ntab,
collect_elems(ets:lookup(NT, {out, V}), ET, 3).
--spec out_edges(digraph(), vertex()) -> [edge()].
+-spec out_edges(G, V) -> Edges when
+ G :: digraph(),
+ V :: vertex(),
+ Edges :: [edge()].
out_edges(G, V) ->
ets:select(G#digraph.ntab, [{{{out, V}, '$1'}, [], ['$1']}]).
--spec add_edge(digraph(), vertex(), vertex()) ->
- edge() | {'error', add_edge_err_rsn()}.
+-spec add_edge(G, V1, V2) -> edge() | {'error', add_edge_err_rsn()} when
+ G :: digraph(),
+ V1 :: vertex(),
+ V2 :: vertex().
add_edge(G, V1, V2) ->
do_add_edge({new_edge_id(G), V1, V2, []}, G).
--spec add_edge(digraph(), vertex(), vertex(), label()) ->
- edge() | {'error', add_edge_err_rsn()}.
+-spec add_edge(G, V1, V2, Label) -> edge() | {'error', add_edge_err_rsn()} when
+ G :: digraph(),
+ V1 :: vertex(),
+ V2 :: vertex(),
+ Label :: label().
add_edge(G, V1, V2, D) ->
do_add_edge({new_edge_id(G), V1, V2, D}, G).
--spec add_edge(digraph(), edge(), vertex(), vertex(), label()) ->
- edge() | {'error', add_edge_err_rsn()}.
+-spec add_edge(G, E, V1, V2, Label) -> edge() | {'error', add_edge_err_rsn()} when
+ G :: digraph(),
+ E :: edge(),
+ V1 :: vertex(),
+ V2 :: vertex(),
+ Label :: label().
add_edge(G, E, V1, V2, D) ->
do_add_edge({E, V1, V2, D}, G).
--spec del_edge(digraph(), edge()) -> 'true'.
+-spec del_edge(G, E) -> 'true' when
+ G :: digraph(),
+ E :: edge().
del_edge(G, E) ->
do_del_edges([E], G).
--spec del_edges(digraph(), [edge()]) -> 'true'.
+-spec del_edges(G, Edges) -> 'true' when
+ G :: digraph(),
+ Edges :: [edge()].
del_edges(G, Es) ->
do_del_edges(Es, G).
--spec no_edges(digraph()) -> non_neg_integer().
+-spec no_edges(G) -> non_neg_integer() when
+ G :: digraph().
no_edges(G) ->
ets:info(G#digraph.etab, size).
--spec edges(digraph()) -> [edge()].
+-spec edges(G) -> Edges when
+ G :: digraph(),
+ Edges :: [edge()].
edges(G) ->
ets:select(G#digraph.etab, [{{'$1', '_', '_', '_'}, [], ['$1']}]).
--spec edges(digraph(), vertex()) -> [edge()].
+-spec edges(G, V) -> Edges when
+ G :: digraph(),
+ V :: vertex(),
+ Edges :: [edge()].
edges(G, V) ->
ets:select(G#digraph.ntab, [{{{out, V},'$1'}, [], ['$1']},
{{{in, V}, '$1'}, [], ['$1']}]).
--spec edge(digraph(), edge()) -> {edge(),vertex(),vertex(),label()} | 'false'.
+-spec edge(G, E) -> {E, V1, V2, Label} | 'false' when
+ G :: digraph(),
+ E :: edge(),
+ V1 :: vertex(),
+ V2 :: vertex(),
+ Label :: label().
edge(G, E) ->
case ets:lookup(G#digraph.etab,E) of
@@ -277,7 +339,7 @@ edge(G, E) ->
%%
%% Generate a "unique" edge identifier (relative to this graph)
%%
--spec new_edge_id(digraph()) -> nonempty_improper_list('$e', non_neg_integer()).
+-spec new_edge_id(digraph()) -> edge().
new_edge_id(G) ->
NT = G#digraph.ntab,
@@ -289,7 +351,7 @@ new_edge_id(G) ->
%%
%% Generate a "unique" vertex identifier (relative to this graph)
%%
--spec new_vertex_id(digraph()) -> nonempty_improper_list('$v', non_neg_integer()).
+-spec new_vertex_id(digraph()) -> vertex().
new_vertex_id(G) ->
NT = G#digraph.ntab,
@@ -444,7 +506,10 @@ acyclic_add_edge(E, V1, V2, Label, G) ->
%% Delete all paths from vertex V1 to vertex V2
%%
--spec del_path(digraph(), vertex(), vertex()) -> 'true'.
+-spec del_path(G, V1, V2) -> 'true' when
+ G :: digraph(),
+ V1 :: vertex(),
+ V2 :: vertex().
del_path(G, V1, V2) ->
case get_path(G, V1, V2) of
@@ -463,7 +528,10 @@ del_path(G, V1, V2) ->
%% been searched.
%%
--spec get_cycle(digraph(), vertex()) -> [vertex(),...] | 'false'.
+-spec get_cycle(G, V) -> Vertices | 'false' when
+ G :: digraph(),
+ V :: vertex(),
+ Vertices :: [vertex(),...].
get_cycle(G, V) ->
case one_path(out_neighbours(G, V), V, [], [V], [V], 2, G, 1) of
@@ -481,7 +549,11 @@ get_cycle(G, V) ->
%% if no path exists false is returned
%%
--spec get_path(digraph(), vertex(), vertex()) -> [vertex(),...] | 'false'.
+-spec get_path(G, V1, V2) -> Vertices | 'false' when
+ G :: digraph(),
+ V1 :: vertex(),
+ V2 :: vertex(),
+ Vertices :: [vertex(),...].
get_path(G, V1, V2) ->
one_path(out_neighbours(G, V1), V2, [], [V1], [V1], 1, G, 1).
@@ -516,7 +588,10 @@ one_path([], _, [], _, _, _, _, _Counter) -> false.
%% Like get_cycle/2, but a cycle of length one is preferred.
%%
--spec get_short_cycle(digraph(), vertex()) -> [vertex(),...] | 'false'.
+-spec get_short_cycle(G, V) -> Vertices | 'false' when
+ G :: digraph(),
+ V :: vertex(),
+ Vertices :: [vertex(),...].
get_short_cycle(G, V) ->
get_short_path(G, V, V).
@@ -526,7 +601,11 @@ get_short_cycle(G, V) ->
%% to find a short path.
%%
--spec get_short_path(digraph(), vertex(), vertex()) -> [vertex(),...] | 'false'.
+-spec get_short_path(G, V1, V2) -> Vertices | 'false' when
+ G :: digraph(),
+ V1 :: vertex(),
+ V2 :: vertex(),
+ Vertices :: [vertex(),...].
get_short_path(G, V1, V2) ->
T = new(),
diff --git a/lib/stdlib/src/digraph_utils.erl b/lib/stdlib/src/digraph_utils.erl
index 080cae4742..e221be15a1 100644
--- a/lib/stdlib/src/digraph_utils.erl
+++ b/lib/stdlib/src/digraph_utils.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -38,48 +38,66 @@
%% A convenient type alias
%%
--type vertices() :: [digraph:vertex()].
-
%%
%% Exported functions
%%
--spec components(digraph()) -> vertices().
+-spec components(Digraph) -> [Component] when
+ Digraph :: digraph(),
+ Component :: [digraph:vertex()].
components(G) ->
forest(G, fun inout/3).
--spec strong_components(digraph()) -> vertices().
+-spec strong_components(Digraph) -> [StrongComponent] when
+ Digraph :: digraph(),
+ StrongComponent :: [digraph:vertex()].
strong_components(G) ->
forest(G, fun in/3, revpostorder(G)).
--spec cyclic_strong_components(digraph()) -> vertices().
+-spec cyclic_strong_components(Digraph) -> [StrongComponent] when
+ Digraph :: digraph(),
+ StrongComponent :: [digraph:vertex()].
cyclic_strong_components(G) ->
remove_singletons(strong_components(G), G, []).
--spec reachable(vertices(), digraph()) -> vertices().
+-spec reachable(Vertices, Digraph) -> Reachable when
+ Digraph :: digraph(),
+ Vertices :: [digraph:vertex()],
+ Reachable :: [digraph:vertex()].
reachable(Vs, G) when is_list(Vs) ->
lists:append(forest(G, fun out/3, Vs, first)).
--spec reachable_neighbours(vertices(), digraph()) -> vertices().
+-spec reachable_neighbours(Vertices, Digraph) -> Reachable when
+ Digraph :: digraph(),
+ Vertices :: [digraph:vertex()],
+ Reachable :: [digraph:vertex()].
reachable_neighbours(Vs, G) when is_list(Vs) ->
lists:append(forest(G, fun out/3, Vs, not_first)).
--spec reaching(vertices(), digraph()) -> vertices().
+-spec reaching(Vertices, Digraph) -> Reaching when
+ Digraph :: digraph(),
+ Vertices :: [digraph:vertex()],
+ Reaching :: [digraph:vertex()].
reaching(Vs, G) when is_list(Vs) ->
lists:append(forest(G, fun in/3, Vs, first)).
--spec reaching_neighbours(vertices(), digraph()) -> vertices().
+-spec reaching_neighbours(Vertices, Digraph) -> Reaching when
+ Digraph :: digraph(),
+ Vertices :: [digraph:vertex()],
+ Reaching :: [digraph:vertex()].
reaching_neighbours(Vs, G) when is_list(Vs) ->
lists:append(forest(G, fun in/3, Vs, not_first)).
--spec topsort(digraph()) -> vertices() | 'false'.
+-spec topsort(Digraph) -> Vertices | 'false' when
+ Digraph :: digraph(),
+ Vertices :: [digraph:vertex()].
topsort(G) ->
L = revpostorder(G),
@@ -88,12 +106,15 @@ topsort(G) ->
false -> false
end.
--spec is_acyclic(digraph()) -> boolean().
+-spec is_acyclic(Digraph) -> boolean() when
+ Digraph :: digraph().
is_acyclic(G) ->
loop_vertices(G) =:= [] andalso topsort(G) =/= false.
--spec arborescence_root(digraph()) -> 'no' | {'yes', digraph:vertex()}.
+-spec arborescence_root(Digraph) -> 'no' | {'yes', Root} when
+ Digraph :: digraph(),
+ Root :: digraph:vertex().
arborescence_root(G) ->
case digraph:no_edges(G) =:= digraph:no_vertices(G) - 1 of
@@ -114,23 +135,30 @@ arborescence_root(G) ->
no
end.
--spec is_arborescence(digraph()) -> boolean().
+-spec is_arborescence(Digraph) -> boolean() when
+ Digraph :: digraph().
is_arborescence(G) ->
arborescence_root(G) =/= no.
--spec is_tree(digraph()) -> boolean().
+-spec is_tree(Digraph) -> boolean() when
+ Digraph :: digraph().
is_tree(G) ->
(digraph:no_edges(G) =:= digraph:no_vertices(G) - 1)
andalso (length(components(G)) =:= 1).
--spec loop_vertices(digraph()) -> vertices().
+-spec loop_vertices(Digraph) -> Vertices when
+ Digraph :: digraph(),
+ Vertices :: [digraph:vertex()].
loop_vertices(G) ->
[V || V <- digraph:vertices(G), is_reflexive_vertex(V, G)].
--spec subgraph(digraph(), vertices()) -> digraph().
+-spec subgraph(Digraph, Vertices) -> SubGraph when
+ Digraph :: digraph(),
+ Vertices :: [digraph:vertex()],
+ SubGraph :: digraph().
subgraph(G, Vs) ->
try
@@ -140,10 +168,12 @@ subgraph(G, Vs) ->
erlang:error(badarg)
end.
--type option() :: {'type', 'inherit' | [digraph:d_type()]}
- | {'keep_labels', boolean()}.
-
--spec subgraph(digraph(), vertices(), [option()]) -> digraph().
+-spec subgraph(Digraph, Vertices, Options) -> SubGraph when
+ Digraph :: digraph(),
+ SubGraph :: digraph(),
+ Vertices :: [digraph:vertex()],
+ Options :: [{'type', SubgraphType} | {'keep_labels', boolean()}],
+ SubgraphType :: 'inherit' | [digraph:d_type()].
subgraph(G, Vs, Opts) ->
try
@@ -153,7 +183,9 @@ subgraph(G, Vs, Opts) ->
erlang:error(badarg)
end.
--spec condensation(digraph()) -> digraph().
+-spec condensation(Digraph) -> CondensedDigraph when
+ Digraph :: digraph(),
+ CondensedDigraph :: digraph().
condensation(G) ->
SCs = strong_components(G),
@@ -176,12 +208,16 @@ condensation(G) ->
ets:delete(I2C),
SCG.
--spec preorder(digraph()) -> vertices().
+-spec preorder(Digraph) -> Vertices when
+ Digraph :: digraph(),
+ Vertices :: [digraph:vertex()].
preorder(G) ->
lists:reverse(revpreorder(G)).
--spec postorder(digraph()) -> vertices().
+-spec postorder(Digraph) -> Vertices when
+ Digraph :: digraph(),
+ Vertices :: [digraph:vertex()].
postorder(G) ->
lists:reverse(revpostorder(G)).
diff --git a/lib/stdlib/src/epp.erl b/lib/stdlib/src/epp.erl
index e5ccaddbb4..d804c1dee5 100644
--- a/lib/stdlib/src/epp.erl
+++ b/lib/stdlib/src/epp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -29,6 +29,7 @@
%%------------------------------------------------------------------------
-type macros() :: [{atom(), term()}].
+-type epp_handle() :: pid().
%% Epp state record.
-record(epp, {file, %Current file
@@ -61,14 +62,23 @@
%% parse_file(FileName, IncludePath, PreDefMacros)
%% macro_defs(Epp)
--spec open(file:name(), [file:name()]) ->
- {'ok', pid()} | {'error', term()}.
+-spec open(FileName, IncludePath) ->
+ {'ok', Epp} | {'error', ErrorDescriptor} when
+ FileName :: file:name(),
+ IncludePath :: [DirectoryName :: file:name()],
+ Epp :: epp_handle(),
+ ErrorDescriptor :: term().
open(Name, Path) ->
open(Name, Path, []).
--spec open(file:name(), [file:name()], macros()) ->
- {'ok', pid()} | {'error', term()}.
+-spec open(FileName, IncludePath, PredefMacros) ->
+ {'ok', Epp} | {'error', ErrorDescriptor} when
+ FileName :: file:name(),
+ IncludePath :: [DirectoryName :: file:name()],
+ PredefMacros :: macros(),
+ Epp :: epp_handle(),
+ ErrorDescriptor :: term().
open(Name, Path, Pdm) ->
Self = self(),
@@ -80,7 +90,8 @@ open(Name, File, StartLocation, Path, Pdm) ->
Epp = spawn(fun() -> server(Self, Name, File, StartLocation,Path,Pdm) end),
epp_request(Epp).
--spec close(pid()) -> 'ok'.
+-spec close(Epp) -> 'ok' when
+ Epp :: epp_handle().
close(Epp) ->
%% Make sure that close is synchronous as a courtesy to test
@@ -93,6 +104,13 @@ close(Epp) ->
scan_erl_form(Epp) ->
epp_request(Epp, scan_erl_form).
+-spec parse_erl_form(Epp) ->
+ {'ok', AbsForm} | {'eof', Line} | {error, ErrorInfo} when
+ Epp :: epp_handle(),
+ AbsForm :: erl_parse:abstract_form(),
+ Line :: erl_scan:line(),
+ ErrorInfo :: erl_scan:error_info() | erl_parse:error_info().
+
parse_erl_form(Epp) ->
case epp_request(Epp, scan_erl_form) of
{ok,Toks} ->
@@ -107,6 +125,9 @@ macro_defs(Epp) ->
%% format_error(ErrorDescriptor) -> String
%% Return a string describing the error.
+-spec format_error(ErrorDescriptor) -> io_lib:chars() when
+ ErrorDescriptor :: term().
+
format_error(cannot_parse) ->
io_lib:format("cannot parse file, giving up", []);
format_error({bad,W}) ->
@@ -146,6 +167,16 @@ format_error(E) -> file:format_error(E).
%% parse_file(FileName, IncludePath, [PreDefMacro]) ->
%% {ok,[Form]} | {error,OpenError}
+-spec parse_file(FileName, IncludePath, PredefMacros) ->
+ {'ok', [Form]} | {error, OpenError} when
+ FileName :: file:name(),
+ IncludePath :: [DirectoryName :: file:name()],
+ Form :: erl_parse:abstract_form() | {'error', ErrorInfo} | {'eof',Line},
+ PredefMacros :: macros(),
+ Line :: erl_scan:line(),
+ ErrorInfo :: erl_scan:error_info() | erl_parse:error_info(),
+ OpenError :: file:posix() | badarg | system_limit.
+
parse_file(Ifile, Path, Predefs) ->
case open(Ifile, Path, Predefs) of
{ok,Epp} ->
diff --git a/lib/stdlib/src/erl_eval.erl b/lib/stdlib/src/erl_eval.erl
index ea1b179ee5..46288cf467 100644
--- a/lib/stdlib/src/erl_eval.erl
+++ b/lib/stdlib/src/erl_eval.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -34,6 +34,37 @@
-import(lists, [reverse/1,foldl/3,member/2]).
+-export_type([binding_struct/0]).
+
+-type(expression() :: erl_parse:abstract_expr()).
+-type(expressions() :: [erl_parse:abstract_expr()]).
+-type(expression_list() :: [expression()]).
+-type(clauses() :: [erl_parse:abstract_clause()]).
+-type(name() :: term()).
+-type(value() :: term()).
+-type(bindings() :: [{name(), value()}]).
+-opaque(binding_struct() :: orddict:orddict()).
+
+-type(lfun_value_handler() :: fun((Name :: atom(),
+ Arguments :: [term()]) ->
+ Value :: value())).
+-type(lfun_eval_handler() :: fun((Name :: atom(),
+ Arguments :: expression_list(),
+ Bindings :: binding_struct()) ->
+ {value,
+ Value :: value(),
+ NewBindings :: binding_struct()})).
+-type(local_function_handler() :: {value, lfun_value_handler()}
+ | {eval, lfun_eval_handler()}
+ | none).
+
+-type(func_spec() :: {Module :: module(), Function :: atom()} | function()).
+-type(nlfun_handler() :: fun((FuncSpec :: func_spec(),
+ Arguments :: [term()]) ->
+ term())).
+-type(non_local_function_handler() :: {value, nlfun_handler()}
+ | none).
+
%% exprs(ExpressionSeq, Bindings)
%% exprs(ExpressionSeq, Bindings, LocalFuncHandler)
%% exprs(ExpressionSeq, Bindings, LocalFuncHandler, ExternalFuncHandler)
@@ -45,6 +76,11 @@
%% that there are valid constructs in Expression to be taken care of
%% by a function handler but considerad errors by erl_lint.
+-spec(exprs(Expressions, Bindings) -> {value, Value, NewBindings} when
+ Expressions :: expressions(),
+ Bindings :: binding_struct(),
+ Value :: value(),
+ NewBindings :: binding_struct()).
exprs(Exprs, Bs) ->
case check_command(Exprs, Bs) of
ok ->
@@ -53,9 +89,25 @@ exprs(Exprs, Bs) ->
erlang:raise(error, Error, [{?MODULE,exprs,2}])
end.
+-spec(exprs(Expressions, Bindings, LocalFunctionHandler) ->
+ {value, Value, NewBindings} when
+ Expressions :: expressions(),
+ Bindings :: binding_struct(),
+ LocalFunctionHandler :: local_function_handler(),
+ Value :: value(),
+ NewBindings :: binding_struct()).
exprs(Exprs, Bs, Lf) ->
exprs(Exprs, Bs, Lf, none, none).
+-spec(exprs(Expressions, Bindings, LocalFunctionHandler,
+ NonLocalFunctionHandler) ->
+ {value, Value, NewBindings} when
+ Expressions :: expressions(),
+ Bindings :: binding_struct(),
+ LocalFunctionHandler :: local_function_handler(),
+ NonLocalFunctionHandler :: non_local_function_handler(),
+ Value :: value(),
+ NewBindings :: binding_struct()).
exprs(Exprs, Bs, Lf, Ef) ->
exprs(Exprs, Bs, Lf, Ef, none).
@@ -75,6 +127,11 @@ exprs([E|Es], Bs0, Lf, Ef, RBs) ->
%%
%% Only expr/2 checks the command by calling erl_lint. See exprs/2.
+-spec(expr(Expression, Bindings) -> {value, Value, NewBindings} when
+ Expression :: expression(),
+ Bindings :: binding_struct(),
+ Value :: value(),
+ NewBindings :: binding_struct()).
expr(E, Bs) ->
case check_command([E], Bs) of
ok ->
@@ -83,9 +140,25 @@ expr(E, Bs) ->
erlang:raise(error, Error, [{?MODULE,expr,2}])
end.
+-spec(expr(Expression, Bindings, LocalFunctionHandler) ->
+ {value, Value, NewBindings} when
+ Expression :: expression(),
+ Bindings :: binding_struct(),
+ LocalFunctionHandler :: local_function_handler(),
+ Value :: value(),
+ NewBindings :: binding_struct()).
expr(E, Bs, Lf) ->
expr(E, Bs, Lf, none, none).
+-spec(expr(Expression, Bindings, LocalFunctionHandler,
+ NonLocalFunctionHandler) ->
+ {value, Value, NewBindings} when
+ Expression :: expression(),
+ Bindings :: binding_struct(),
+ LocalFunctionHandler :: local_function_handler(),
+ NonLocalFunctionHandler :: non_local_function_handler(),
+ Value :: value(),
+ NewBindings :: binding_struct()).
expr(E, Bs, Lf, Ef) ->
expr(E, Bs, Lf, Ef, none).
@@ -114,6 +187,16 @@ fun_data(F) when is_function(F) ->
fun_data(_T) ->
false.
+-spec(expr(Expression, Bindings, LocalFunctionHandler,
+ NonLocalFunctionHandler, ReturnFormat) ->
+ {value, Value, NewBindings} | Value when
+ Expression :: expression(),
+ Bindings :: binding_struct(),
+ LocalFunctionHandler :: local_function_handler(),
+ NonLocalFunctionHandler :: non_local_function_handler(),
+ ReturnFormat :: none | value,
+ Value :: value(),
+ NewBindings :: binding_struct()).
expr({var,_,V}, Bs, _Lf, _Ef, RBs) ->
case binding(V, Bs) of
{value,Val} ->
@@ -384,12 +467,9 @@ local_func(Func, As0, Bs0, {value,F}, value) ->
local_func(Func, As0, Bs0, {value,F}, RBs) ->
{As1,Bs1} = expr_list(As0, Bs0, {value,F}),
ret_expr(F(Func, As1), Bs1, RBs);
-local_func(Func, As0, Bs0, {value,F,Eas}, value) ->
- {As1,_Bs1} = expr_list(As0, Bs0, {value,F,Eas}),
- apply(F, [Func,As1|Eas]);
local_func(Func, As0, Bs0, {value,F,Eas}, RBs) ->
- {As1,Bs1} = expr_list(As0, Bs0, {value,F,Eas}),
- ret_expr(apply(F, [Func,As1|Eas]), Bs1, RBs);
+ Fun = fun(Name, Args) -> apply(F, [Name,Args|Eas]) end,
+ local_func(Func, As0, Bs0, {value, Fun}, RBs);
local_func(Func, As, Bs, {eval,F}, RBs) ->
local_func2(F(Func, As, Bs), RBs);
local_func(Func, As, Bs, {eval,F,Eas}, RBs) ->
@@ -613,12 +693,33 @@ eval_fun([], As, _Bs, _Lf, _Ef, _RBs) ->
%% expr_list(ExpressionList, Bindings, LocalFuncHandler, ExternalFuncHandler)
%% Evaluate a list of expressions "in parallel" at the same level.
+-spec(expr_list(ExpressionList, Bindings) -> {ValueList, NewBindings} when
+ ExpressionList :: expression_list(),
+ Bindings :: binding_struct(),
+ ValueList :: [value()],
+ NewBindings :: binding_struct()).
expr_list(Es, Bs) ->
expr_list(Es, Bs, none, none).
+-spec(expr_list(ExpressionList, Bindings, LocalFunctionHandler) ->
+ {ValueList, NewBindings} when
+ ExpressionList :: expression_list(),
+ Bindings :: binding_struct(),
+ LocalFunctionHandler :: local_function_handler(),
+ ValueList :: [value()],
+ NewBindings :: binding_struct()).
expr_list(Es, Bs, Lf) ->
expr_list(Es, Bs, Lf, none).
+-spec(expr_list(ExpressionList, Bindings, LocalFunctionHandler,
+ NonLocalFunctionHandler) ->
+ {ValueList, NewBindings} when
+ ExpressionList :: expression_list(),
+ Bindings :: binding_struct(),
+ LocalFunctionHandler :: local_function_handler(),
+ NonLocalFunctionHandler :: non_local_function_handler(),
+ ValueList :: [value()],
+ NewBindings :: binding_struct()).
expr_list(Es, Bs, Lf, Ef) ->
expr_list(Es, [], Bs, Bs, Lf, Ef).
@@ -757,6 +858,15 @@ send_all([], _) -> true.
%% match_clause -> {Body, Bindings} or nomatch
+-spec(match_clause(Clauses, ValueList, Bindings, LocalFunctionHandler) ->
+ {Body, NewBindings} | nomatch when
+ Clauses :: clauses(),
+ ValueList :: [value()],
+ Bindings :: binding_struct(),
+ LocalFunctionHandler :: local_function_handler(),
+ Body :: expression_list(),
+ NewBindings :: binding_struct()).
+
match_clause(Cs, Vs, Bs, Lf) ->
match_clause(Cs, Vs, Bs, Lf, none).
@@ -973,18 +1083,30 @@ match_list(_, _, _Bs, _BBs) ->
%% add_binding(Name, Value, Bindings)
%% del_binding(Name, Bindings)
+-spec(new_bindings() -> binding_struct()).
new_bindings() -> orddict:new().
+-spec(bindings(BindingStruct :: binding_struct()) -> bindings()).
bindings(Bs) -> orddict:to_list(Bs).
+-spec(binding(Name, BindingStruct) -> {value, value()} | unbound when
+ Name :: name(),
+ BindingStruct :: binding_struct()).
binding(Name, Bs) ->
case orddict:find(Name, Bs) of
{ok,Val} -> {value,Val};
error -> unbound
end.
+-spec(add_binding(Name, Value, BindingStruct) -> binding_struct() when
+ Name :: name(),
+ Value :: value(),
+ BindingStruct :: binding_struct()).
add_binding(Name, Val, Bs) -> orddict:store(Name, Val, Bs).
+-spec(del_binding(Name, BindingStruct) -> binding_struct() when
+ Name :: name(),
+ BindingStruct :: binding_struct()).
del_binding(Name, Bs) -> orddict:erase(Name, Bs).
add_bindings(Bs1, Bs2) ->
diff --git a/lib/stdlib/src/erl_expand_records.erl b/lib/stdlib/src/erl_expand_records.erl
index 61ce41f714..eada563914 100644
--- a/lib/stdlib/src/erl_expand_records.erl
+++ b/lib/stdlib/src/erl_expand_records.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -38,6 +38,10 @@
checked_ra=[] % succesfully accessed records
}).
+-spec(module(AbsForms, CompileOptions) -> AbsForms when
+ AbsForms :: [erl_parse:abstract_form()],
+ CompileOptions :: [compile:option()]).
+
%% Is is assumed that Fs is a valid list of forms. It should pass
%% erl_lint without errors.
module(Fs0, Opts0) ->
diff --git a/lib/stdlib/src/erl_internal.erl b/lib/stdlib/src/erl_internal.erl
index b30b02a96f..478f05e792 100644
--- a/lib/stdlib/src/erl_internal.erl
+++ b/lib/stdlib/src/erl_internal.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -54,7 +54,9 @@
%%---------------------------------------------------------------------------
%% Erlang builtin functions allowed in guards.
--spec guard_bif(Name::atom(), Arity::arity()) -> boolean().
+-spec guard_bif(Name, Arity) -> boolean() when
+ Name :: atom(),
+ Arity :: arity().
guard_bif(abs, 1) -> true;
guard_bif(float, 1) -> true;
@@ -92,7 +94,9 @@ guard_bif(binary_part, 3) -> true;
guard_bif(Name, A) when is_atom(Name), is_integer(A) -> false.
%% Erlang type tests.
--spec type_test(Name::atom(), Arity::arity()) -> boolean().
+-spec type_test(Name, Arity) -> boolean() when
+ Name :: atom(),
+ Arity :: arity().
type_test(Name, Arity) ->
new_type_test(Name, Arity) orelse old_type_test(Name, Arity).
@@ -135,7 +139,9 @@ old_type_test(record, 2) -> true;
old_type_test(function, 1) -> true;
old_type_test(Name, A) when is_atom(Name), is_integer(A) -> false.
--spec arith_op(Op::atom(), Arity::arity()) -> boolean().
+-spec arith_op(OpName, Arity) -> boolean() when
+ OpName :: atom(),
+ Arity :: arity().
arith_op('+', 1) -> true;
arith_op('-', 1) -> true;
@@ -153,7 +159,9 @@ arith_op('bsl', 2) -> true;
arith_op('bsr', 2) -> true;
arith_op(Op, A) when is_atom(Op), is_integer(A) -> false.
--spec bool_op(Op::atom(), Arity::arity()) -> boolean().
+-spec bool_op(OpName, Arity) -> boolean() when
+ OpName :: atom(),
+ Arity :: arity().
bool_op('not', 1) -> true;
bool_op('and', 2) -> true;
@@ -161,7 +169,9 @@ bool_op('or', 2) -> true;
bool_op('xor', 2) -> true;
bool_op(Op, A) when is_atom(Op), is_integer(A) -> false.
--spec comp_op(Op::atom(), Arity::arity()) -> boolean().
+-spec comp_op(OpName, Arity) -> boolean() when
+ OpName :: atom(),
+ Arity :: arity().
comp_op('==', 2) -> true;
comp_op('/=', 2) -> true;
@@ -173,18 +183,25 @@ comp_op('=:=', 2) -> true;
comp_op('=/=', 2) -> true;
comp_op(Op, A) when is_atom(Op), is_integer(A) -> false.
--spec list_op(Op::atom(), Arity::arity()) -> boolean().
+-spec list_op(OpName, Arity) -> boolean() when
+ OpName :: atom(),
+ Arity :: arity().
list_op('++', 2) -> true;
list_op('--', 2) -> true;
list_op(Op, A) when is_atom(Op), is_integer(A) -> false.
--spec send_op(Op::atom(), Arity::arity()) -> boolean().
+-spec send_op(OpName, Arity) -> boolean() when
+ OpName :: atom(),
+ Arity :: arity().
send_op('!', 2) -> true;
send_op(Op, A) when is_atom(Op), is_integer(A) -> false.
--spec op_type(atom(), arity()) -> 'arith' | 'bool' | 'comp' | 'list' | 'send'.
+-spec op_type(OpName, Arity) -> Type when
+ OpName :: atom(),
+ Arity :: arity(),
+ Type :: 'arith' | 'bool' | 'comp' | 'list' | 'send'.
op_type('+', 1) -> arith;
op_type('-', 1) -> arith;
@@ -221,7 +238,9 @@ op_type('!', 2) -> send.
bif(erlang, Name, Arity) -> bif(Name, Arity);
bif(M, F, A) when is_atom(M), is_atom(F), is_integer(A) -> false.
--spec bif(Name::atom(), Arity::arity()) -> boolean().
+-spec bif(Name, Arity) -> boolean() when
+ Name :: atom(),
+ Arity::arity().
%% Returns true if erlang:Name/Arity is an auto-imported BIF, false otherwise.
%% Use erlang:is_bultin(Mod, Name, Arity) to find whether a function is a BIF
%% (meaning implemented in C) or not.
diff --git a/lib/stdlib/src/erl_lint.erl b/lib/stdlib/src/erl_lint.erl
index cfb9f0ca98..dd0b9bc2ab 100644
--- a/lib/stdlib/src/erl_lint.erl
+++ b/lib/stdlib/src/erl_lint.erl
@@ -128,10 +128,15 @@ value_option(Flag, Default, On, OnVal, Off, OffVal, Opts) ->
}).
-type lint_state() :: #lint{}.
+-type error_description() :: term().
+-type error_info() :: {erl_scan:line(), module(), error_description()}.
%% format_error(Error)
%% Return a string describing the error.
+-spec format_error(ErrorDescriptor) -> io_lib:chars() when
+ ErrorDescriptor :: error_description().
+
format_error(undefined_module) ->
"no module definition";
format_error({bad_module_name, M}) ->
@@ -419,16 +424,39 @@ used_vars(Exprs, BindingsList) ->
%% apply_lambda/2 has been called to shut lint up. N.B. these lists are
%% really all ordsets!
+-spec(module(AbsForms) -> {ok, Warnings} | {error, Errors, Warnings} when
+ AbsForms :: [erl_parse:abstract_form()],
+ Warnings :: [{file:filename(),[ErrorInfo]}],
+ Errors :: [{FileName2 :: file:filename(),[ErrorInfo]}],
+ ErrorInfo :: error_info()).
+
module(Forms) ->
Opts = compiler_options(Forms),
St = forms(Forms, start("nofile", Opts)),
return_status(St).
+-spec(module(AbsForms, FileName) ->
+ {ok, Warnings} | {error, Errors, Warnings} when
+ AbsForms :: [erl_parse:abstract_form()],
+ FileName :: atom() | string(),
+ Warnings :: [{file:filename(),[ErrorInfo]}],
+ Errors :: [{FileName2 :: file:filename(),[ErrorInfo]}],
+ ErrorInfo :: error_info()).
+
module(Forms, FileName) ->
Opts = compiler_options(Forms),
St = forms(Forms, start(FileName, Opts)),
return_status(St).
+-spec(module(AbsForms, FileName, CompileOptions) ->
+ {ok, Warnings} | {error, Errors, Warnings} when
+ AbsForms :: [erl_parse:abstract_form()],
+ FileName :: atom() | string(),
+ CompileOptions :: [compile:option()],
+ Warnings :: [{file:filename(),[ErrorInfo]}],
+ Errors :: [{FileName2 :: file:filename(),[ErrorInfo]}],
+ ErrorInfo :: error_info()).
+
module(Forms, FileName, Opts0) ->
%% We want the options given on the command line to take
%% precedence over options in the module.
@@ -1877,6 +1905,9 @@ gexpr_list(Es, Vt, St) ->
%% is_guard_test(Expression) -> boolean().
%% Test if a general expression is a guard test.
+-spec is_guard_test(Expr) -> boolean() when
+ Expr :: erl_parse:abstract_expr().
+
is_guard_test(E) ->
is_guard_test2(E, dict:new()).
diff --git a/lib/stdlib/src/erl_parse.yrl b/lib/stdlib/src/erl_parse.yrl
index 15b45d72f4..bd5d65a1e1 100644
--- a/lib/stdlib/src/erl_parse.yrl
+++ b/lib/stdlib/src/erl_parse.yrl
@@ -511,6 +511,15 @@ Erlang code.
%% of the generated .erl file by the HiPE compiler. Please do not remove.
-compile([{hipe,[{regalloc,linear_scan}]}]).
+-export_type([abstract_clause/0, abstract_expr/0, abstract_form/0,
+ error_info/0]).
+
+-type abstract_clause() :: term().
+-type abstract_expr() :: term().
+-type abstract_form() :: term().
+-type error_description() :: term().
+-type error_info() :: {erl_scan:line(), module(), error_description()}.
+-type token() :: {Tag :: atom(), Line :: erl_scan:line()}.
%% mkop(Op, Arg) -> {op,Line,Op,Arg}.
%% mkop(Left, Op, Right) -> {op,Line,Op,Left,Right}.
@@ -534,11 +543,19 @@ Erlang code.
%% These really suck and are only here until Calle gets multiple
%% entry points working.
+-spec parse_form(Tokens) -> {ok, AbsForm} | {error, ErrorInfo} when
+ Tokens :: [token()],
+ AbsForm :: abstract_form(),
+ ErrorInfo :: error_info().
parse_form([{'-',L1},{atom,L2,spec}|Tokens]) ->
parse([{'-',L1},{'spec',L2}|Tokens]);
parse_form(Tokens) ->
parse(Tokens).
+-spec parse_exprs(Tokens) -> {ok, ExprList} | {error, ErrorInfo} when
+ Tokens :: [token()],
+ ExprList :: [abstract_expr()],
+ ErrorInfo :: error_info().
parse_exprs(Tokens) ->
case parse([{atom,0,f},{'(',0},{')',0},{'->',0}|Tokens]) of
{ok,{function,_Lf,f,0,[{clause,_Lc,[],[],Exprs}]}} ->
@@ -546,6 +563,10 @@ parse_exprs(Tokens) ->
{error,_} = Err -> Err
end.
+-spec parse_term(Tokens) -> {ok, Term} | {error, ErrorInfo} when
+ Tokens :: [token()],
+ Term :: term(),
+ ErrorInfo :: error_info().
parse_term(Tokens) ->
case parse([{atom,0,f},{'(',0},{')',0},{'->',0}|Tokens]) of
{ok,{function,_Lf,f,0,[{clause,_Lc,[],[],[Expr]}]}} ->
@@ -830,6 +851,7 @@ check_clauses(Cs, Name, Arity) ->
build_try(L,Es,Scs,{Ccs,As}) ->
{'try',L,Es,Scs,Ccs,As}.
+-spec ret_err(_, _) -> no_return().
ret_err(L, S) ->
{location,Location} = get_attribute(L, location),
return_error(Location, S).
@@ -846,10 +868,11 @@ mapl(F, [H|T]) ->
mapl(_, []) ->
[].
-%% normalise(AbsTerm)
-%% abstract(Term)
%% Convert between the abstract form of a term and a term.
+-spec normalise(AbsTerm) -> Data when
+ AbsTerm :: abstract_expr(),
+ Data :: term().
normalise({char,_,C}) -> C;
normalise({integer,_,I}) -> I;
normalise({float,_,F}) -> F;
@@ -887,6 +910,9 @@ normalise_list([H|T]) ->
normalise_list([]) ->
[].
+-spec abstract(Data) -> AbsTerm when
+ Data :: term(),
+ AbsTerm :: abstract_expr().
abstract(T) when is_integer(T) -> {integer,0,T};
abstract(T) when is_float(T) -> {float,0,T};
abstract(T) when is_atom(T) -> {atom,0,T};
@@ -955,13 +981,18 @@ abstract_list([H|T], Line) ->
abstract_list([], _Line) ->
[].
-%% tokens(AbsTerm) -> [Token]
-%% tokens(AbsTerm, More) -> [Token]
%% Generate a list of tokens representing the abstract term.
+-spec tokens(AbsTerm) -> Tokens when
+ AbsTerm :: abstract_expr(),
+ Tokens :: [token()].
tokens(Abs) ->
tokens(Abs, []).
+-spec tokens(AbsTerm, MoreTokens) -> Tokens when
+ AbsTerm :: abstract_expr(),
+ MoreTokens :: [token()],
+ Tokens :: [token()].
tokens({char,L,C}, More) -> [{char,L,C}|More];
tokens({integer,L,N}, More) -> [{integer,L,N}|More];
tokens({float,L,F}, More) -> [{float,L,F}|More];
diff --git a/lib/stdlib/src/erl_pp.erl b/lib/stdlib/src/erl_pp.erl
index 66c80a45cb..7dc19f2e9b 100644
--- a/lib/stdlib/src/erl_pp.erl
+++ b/lib/stdlib/src/erl_pp.erl
@@ -31,25 +31,53 @@
-define(MAXLINE, 72).
+-type(hook_function() :: none
+ | fun((Expr :: erl_parse:abstract_expr(),
+ CurrentIndentation :: integer(),
+ CurrentPrecedence :: non_neg_integer(),
+ HookFunction :: hook_function()) ->
+ io_lib:chars())).
+
%%%
%%% Exported functions
%%%
+-spec(form(Form) -> io_lib:chars() when
+ Form :: erl_parse:abstract_form()).
+
form(Thing) ->
form(Thing, none).
+-spec(form(Form, HookFunction) -> io_lib:chars() when
+ Form :: erl_parse:abstract_form(),
+ HookFunction :: hook_function()).
+
form(Thing, Hook) ->
frmt(lform(Thing, Hook)).
+-spec(attribute(Attribute) -> io_lib:chars() when
+ Attribute :: erl_parse:abstract_form()).
+
attribute(Thing) ->
attribute(Thing, none).
+-spec(attribute(Attribute, HookFunction) -> io_lib:chars() when
+ Attribute :: erl_parse:abstract_form(),
+ HookFunction :: hook_function()).
+
attribute(Thing, Hook) ->
frmt(lattribute(Thing, Hook)).
+-spec(function(Function) -> io_lib:chars() when
+ Function :: erl_parse:abstract_form()).
+
function(F) ->
function(F, none).
+-spec(function(Function, HookFunction) -> io_lib:chars() when
+ Function :: erl_parse:abstract_form(),
+ HookFunction :: hook_function()).
+
function(F, Hook) ->
frmt(lfunction(F, Hook)).
@@ -59,30 +87,67 @@ rule(R) ->
rule(R, Hook) ->
frmt(lrule(R, Hook)).
+-spec(guard(Guard) -> io_lib:chars() when
+ Guard :: [erl_parse:abstract_expr()]).
+
guard(Gs) ->
guard(Gs, none).
+-spec(guard(Guard, HookFunction) -> io_lib:chars() when
+ Guard :: [erl_parse:abstract_expr()],
+ HookFunction :: hook_function()).
+
guard(Gs, Hook) ->
frmt(lguard(Gs, Hook)).
+-spec(exprs(Expressions) -> io_lib:chars() when
+ Expressions :: [erl_parse:abstract_expr()]).
+
exprs(Es) ->
exprs(Es, 0, none).
+-spec(exprs(Expressions, HookFunction) -> io_lib:chars() when
+ Expressions :: [erl_parse:abstract_expr()],
+ HookFunction :: hook_function()).
+
exprs(Es, Hook) ->
exprs(Es, 0, Hook).
+-spec(exprs(Expressions, Indent, HookFunction) -> io_lib:chars() when
+ Expressions :: [erl_parse:abstract_expr()],
+ Indent :: integer(),
+ HookFunction :: hook_function()).
+
exprs(Es, I, Hook) ->
frmt({seq,[],[],[$,],lexprs(Es, Hook)}, I).
+-spec(expr(Expression) -> io_lib:chars() when
+ Expression :: erl_parse:abstract_expr()).
+
expr(E) ->
frmt(lexpr(E, 0, none)).
+-spec(expr(Expression, HookFunction) -> io_lib:chars() when
+ Expression :: erl_parse:abstract_expr(),
+ HookFunction :: hook_function()).
+
expr(E, Hook) ->
frmt(lexpr(E, 0, Hook)).
+-spec(expr(Expression, Indent, HookFunction) -> io_lib:chars() when
+ Expression :: erl_parse:abstract_expr(),
+ Indent :: integer(),
+ HookFunction :: hook_function()).
+
expr(E, I, Hook) ->
frmt(lexpr(E, 0, Hook), I).
+-spec(expr(Expression, Indent, Precedence, HookFunction) -> io_lib:chars() when
+ Expression :: erl_parse:abstract_expr(),
+ Indent :: integer(),
+ Precedence :: non_neg_integer(),
+ HookFunction :: hook_function()).
+
expr(E, I, P, Hook) ->
frmt(lexpr(E, P, Hook), I).
diff --git a/lib/stdlib/src/erl_scan.erl b/lib/stdlib/src/erl_scan.erl
index 18f64c46d0..718ca2e91a 100644
--- a/lib/stdlib/src/erl_scan.erl
+++ b/lib/stdlib/src/erl_scan.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -99,7 +99,8 @@
%%----------------------------------------------------------------------------
--spec format_error(Error :: term()) -> string().
+-spec format_error(ErrorDescriptor) -> string() when
+ ErrorDescriptor :: error_description().
format_error({string,Quote,Head}) ->
lists:flatten(["unterminated " ++ string_thing(Quote) ++
" starting with " ++
@@ -112,20 +113,33 @@ format_error({base,Base}) ->
format_error(Other) ->
lists:flatten(io_lib:write(Other)).
--type string_return() :: {'ok', tokens(), location()}
- | {'error', error_info(), location()}.
-
--spec string(String :: string()) -> string_return().
+-spec string(String) -> Return when
+ String :: string(),
+ Return :: {'ok', Tokens :: tokens(), EndLocation}
+ | {'error', ErrorInfo :: error_info(), ErrorLocation},
+ EndLocation :: location(),
+ ErrorLocation :: location().
string(String) ->
string(String, 1, []).
--spec string(String :: string(), StartLocation :: location()) ->
- string_return().
+-spec string(String, StartLocation) -> Return when
+ String :: string(),
+ Return :: {'ok', Tokens :: tokens(), EndLocation}
+ | {'error', ErrorInfo :: error_info(), ErrorLocation},
+ StartLocation :: location(),
+ EndLocation :: location(),
+ ErrorLocation :: location().
string(String, StartLocation) ->
string(String, StartLocation, []).
--spec string(String :: string(), StartLocation :: location(),
- Options :: options()) -> string_return().
+-spec string(String, StartLocation, Options) -> Return when
+ String :: string(),
+ Options :: options(),
+ Return :: {'ok', Tokens :: tokens(), EndLocation}
+ | {'error', ErrorInfo :: error_info(), ErrorLocation},
+ StartLocation :: location(),
+ EndLocation :: location(),
+ ErrorLocation :: location().
string(String, Line, Options) when ?STRING(String), ?ALINE(Line) ->
string1(String, options(Options), Line, no_col, []);
string(String, {Line,Column}, Options) when ?STRING(String),
@@ -136,29 +150,37 @@ string(String, {Line,Column}, Options) when ?STRING(String),
-type char_spec() :: string() | 'eof'.
-type cont_fun() :: fun((char_spec(), #erl_scan{}, line(), column(),
tokens(), any()) -> any()).
--opaque return_cont() :: {string(), column(), tokens(), line(),
- #erl_scan{}, cont_fun(), any()}.
--type cont() :: return_cont() | [].
--type tokens_result() :: {'ok', tokens(), location()}
- | {'eof', location()}
- | {'error', error_info(), location()}.
--type tokens_return() :: {'done', tokens_result(), char_spec()}
- | {'more', return_cont()}.
-
--spec tokens(Cont :: cont(), CharSpec :: char_spec(),
- StartLocation :: location()) -> tokens_return().
+-opaque return_cont() :: {erl_scan_continuation,
+ string(), column(), tokens(), line(),
+ #erl_scan{}, any(), cont_fun()}.
+-type tokens_result() :: {'ok', Tokens :: tokens(), EndLocation :: location()}
+ | {'eof', EndLocation :: location()}
+ | {'error', ErrorInfo :: error_info(),
+ EndLocation :: location()}.
+
+-spec tokens(Continuation, CharSpec, StartLocation) -> Return when
+ Continuation :: return_cont() | [],
+ CharSpec :: char_spec(),
+ StartLocation :: location(),
+ Return :: {'done',Result :: tokens_result(),LeftOverChars :: char_spec()}
+ | {'more', Continuation1 :: return_cont()}.
tokens(Cont, CharSpec, StartLocation) ->
tokens(Cont, CharSpec, StartLocation, []).
--spec tokens(Cont :: cont(), CharSpec :: char_spec(),
- StartLocation :: location(), Options :: options()) ->
- tokens_return().
+-spec tokens(Continuation, CharSpec, StartLocation, Options) -> Return when
+ Continuation :: return_cont() | [],
+ CharSpec :: char_spec(),
+ StartLocation :: location(),
+ Options :: options(),
+ Return :: {'done',Result :: tokens_result(),LeftOverChars :: char_spec()}
+ | {'more', Continuation1 :: return_cont()}.
tokens([], CharSpec, Line, Options) when ?ALINE(Line) ->
tokens1(CharSpec, options(Options), Line, no_col, [], fun scan/6, []);
tokens([], CharSpec, {Line,Column}, Options) when ?ALINE(Line),
?COLUMN(Column) ->
tokens1(CharSpec, options(Options), Line, Column, [], fun scan/6, []);
-tokens({Cs,Col,Toks,Line,St,Any,Fun}, CharSpec, _Loc, _Opts) ->
+tokens({erl_scan_continuation,Cs,Col,Toks,Line,St,Any,Fun},
+ CharSpec, _Loc, _Opts) ->
tokens1(Cs++CharSpec, St, Line, Col, Toks, Fun, Any).
-type attribute_item() :: 'column' | 'length' | 'line'
@@ -172,13 +194,22 @@ tokens({Cs,Col,Toks,Line,St,Any,Fun}, CharSpec, _Loc, _Opts) ->
-type token_info() :: {'category', category()} | {'symbol', symbol()}
| attribute_info().
--spec token_info(token()) -> [token_info()].
+-spec token_info(Token) -> TokenInfo when
+ Token :: token(),
+ TokenInfo :: [TokenInfoTuple :: token_info()].
token_info(Token) ->
Items = [category,column,length,line,symbol,text], % undefined order
token_info(Token, Items).
--spec token_info(token(), token_item()) -> token_info() | 'undefined';
- (token(), [token_item()]) -> [token_info()].
+-spec token_info(Token, TokenItem) -> TokenInfo | 'undefined' when
+ Token :: token(),
+ TokenItem :: token_item(),
+ TokenInfo :: TokenInfoTuple :: token_info();
+ (Token, TokenItems) -> [TokenInfo] when
+ Token :: token(),
+ TokenItems :: [TokenItem],
+ TokenItem :: token_item(),
+ TokenInfo :: [TokenInfoTuple :: token_info()].
token_info(_Token, []) ->
[];
token_info(Token, [Item|Items]) when is_atom(Item) ->
@@ -201,14 +232,23 @@ token_info({_Category,Attrs}, Item) ->
token_info({_Category,Attrs,_Symbol}, Item) ->
attributes_info(Attrs, Item).
--spec attributes_info(attributes()) -> [attribute_info()].
+-spec attributes_info(Attributes) -> AttributesInfo when
+ Attributes :: attributes(),
+ AttributesInfo :: [AttributeInfoTuple :: attribute_info()].
attributes_info(Attributes) ->
Items = [column,length,line,text], % undefined order
attributes_info(Attributes, Items).
--spec attributes_info(attributes(), attribute_item()) ->
- attribute_info() | 'undefined';
- (attributes(), [attribute_item()]) -> [attribute_info()].
+-spec attributes_info(Attributes, AttributeItem) ->
+ AttributeInfo | 'undefined' when
+ Attributes :: attributes(),
+ AttributeItem :: attribute_item(),
+ AttributeInfo :: AttributeInfoTuple :: attribute_info();
+ (Attributes, AttributeItems) -> [AttributeInfo] when
+ Attributes :: attributes(),
+ AttributeItems :: [AttributeItem],
+ AttributeItem :: attribute_item(),
+ AttributeInfo :: [AttributeInfoTuple :: attribute_info()].
attributes_info(_Attrs, []) ->
[];
attributes_info(Attrs, [A|As]) when is_atom(A) ->
@@ -265,9 +305,10 @@ attributes_info(Attrs, text=Item) ->
attributes_info(T1, T2) ->
erlang:error(badarg, [T1,T2]).
--type setlineattr_fun() :: fun((info_line()) -> info_line()).
-
--spec set_attribute('line', attributes(), setlineattr_fun()) -> attributes().
+-spec set_attribute(AttributeItem, Attributes, SetAttributeFun) -> Attributes when
+ AttributeItem :: 'line',
+ Attributes :: attributes(),
+ SetAttributeFun :: fun((info_line()) -> info_line()).
set_attribute(Tag, Attributes, Fun) when ?SETATTRFUN(Fun) ->
set_attr(Tag, Attributes, Fun).
@@ -374,7 +415,7 @@ set_attr(T1, T2, T3) ->
tokens1(Cs, St, Line, Col, Toks, Fun, Any) when ?STRING(Cs); Cs =:= eof ->
case Fun(Cs, St, Line, Col, Toks, Any) of
{more,{Cs0,Ncol,Ntoks,Nline,Nany,Nfun}} ->
- {more,{Cs0,Ncol,Ntoks,Nline,St,Nany,Nfun}};
+ {more,{erl_scan_continuation,Cs0,Ncol,Ntoks,Nline,St,Nany,Nfun}};
{ok,Toks0,eof,Nline,Ncol} ->
Res = case Toks0 of
[] ->
@@ -1285,7 +1326,7 @@ tabs(8) -> "\t\t\t\t\t\t\t\t";
tabs(9) -> "\t\t\t\t\t\t\t\t\t";
tabs(10) -> "\t\t\t\t\t\t\t\t\t\t".
--spec reserved_word(atom()) -> boolean().
+-spec reserved_word(Atom :: atom()) -> boolean().
reserved_word('after') -> true;
reserved_word('begin') -> true;
reserved_word('case') -> true;
diff --git a/lib/stdlib/src/ets.erl b/lib/stdlib/src/ets.erl
index 6e6e949e2c..afa914a456 100644
--- a/lib/stdlib/src/ets.erl
+++ b/lib/stdlib/src/ets.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -42,7 +42,7 @@
-export([i/0, i/1, i/2, i/3]).
--export_type([tab/0, tid/0]).
+-export_type([tab/0, tid/0, match_spec/0]).
%%-----------------------------------------------------------------------------
@@ -51,22 +51,9 @@
%% a similar definition is also in erl_types
-opaque tid() :: integer().
--type ext_info() :: 'md5sum' | 'object_count'.
--type protection() :: 'private' | 'protected' | 'public'.
--type type() :: 'bag' | 'duplicate_bag' | 'ordered_set' | 'set'.
-
--type table_info() :: {'name', atom()}
- | {'type', type()}
- | {'protection', protection()}
- | {'named_table', boolean()}
- | {'keypos', non_neg_integer()}
- | {'size', non_neg_integer()}
- | {'extended_info', [ext_info()]}
- | {'version', {non_neg_integer(), non_neg_integer()}}.
-
%% these ones are also defined in erl_bif_types
-type match_pattern() :: atom() | tuple().
--type match_specs() :: [{match_pattern(), [_], [_]}].
+-type match_spec() :: [{match_pattern(), [_], [_]}].
%%-----------------------------------------------------------------------------
@@ -86,6 +73,7 @@
%% insert/2
%% is_compiled_ms/1
%% last/1
+%% member/2
%% next/2
%% prev/2
%% rename/2
@@ -101,11 +89,14 @@
%% select/1
%% select/2
%% select/3
+%% select_count/2
%% select_reverse/1
%% select_reverse/2
%% select_reverse/3
%% select_delete/2
+%% setopts/2
%% update_counter/3
+%% update_element/3
%%
-opaque comp_match_spec() :: any(). %% this one is REALLY opaque
@@ -119,7 +110,9 @@ match_spec_run(List, CompiledMS) ->
| {tab(),integer(),integer(),binary(),list(),integer()}
| {tab(),_,_,integer(),binary(),list(),integer(),integer()}.
--spec repair_continuation(continuation(), match_specs()) -> continuation().
+-spec repair_continuation(Continuation, MatchSpec) -> Continuation when
+ Continuation :: continuation(),
+ MatchSpec :: match_spec().
%% $end_of_table is an allowed continuation in ets...
repair_continuation('$end_of_table', _) ->
@@ -153,7 +146,9 @@ repair_continuation(Untouched = {Table,N1,N2,Bin,L,N3}, MS)
{Table,N1,N2,ets:match_spec_compile(MS),L,N3}
end.
--spec fun2ms(function()) -> match_specs().
+-spec fun2ms(LiteralFun) -> MatchSpec when
+ LiteralFun :: function(),
+ MatchSpec :: match_spec().
fun2ms(ShellFun) when is_function(ShellFun) ->
%% Check that this is really a shell fun...
@@ -177,7 +172,13 @@ fun2ms(ShellFun) when is_function(ShellFun) ->
shell]}})
end.
--spec foldl(fun((_, term()) -> term()), term(), tab()) -> term().
+-spec foldl(Function, Acc0, Tab) -> Acc1 when
+ Function :: fun((Element :: term(), AccIn) -> AccOut),
+ Tab :: tab(),
+ Acc0 :: term(),
+ Acc1 :: term(),
+ AccIn :: term(),
+ AccOut :: term().
foldl(F, Accu, T) ->
ets:safe_fixtable(T, true),
@@ -198,7 +199,13 @@ do_foldl(F, Accu0, Key, T) ->
ets:next(T, Key), T)
end.
--spec foldr(fun((_, term()) -> term()), term(), tab()) -> term().
+-spec foldr(Function, Acc0, Tab) -> Acc1 when
+ Function :: fun((Element :: term(), AccIn) -> AccOut),
+ Tab :: tab(),
+ Acc0 :: term(),
+ Acc1 :: term(),
+ AccIn :: term(),
+ AccOut :: term().
foldr(F, Accu, T) ->
ets:safe_fixtable(T, true),
@@ -219,7 +226,9 @@ do_foldr(F, Accu0, Key, T) ->
ets:prev(T, Key), T)
end.
--spec from_dets(tab(), dets:tab_name()) -> 'true'.
+-spec from_dets(Tab, DetsTab) -> 'true' when
+ Tab :: tab(),
+ DetsTab :: dets:tab_name().
from_dets(EtsTable, DetsTable) ->
case (catch dets:to_ets(DetsTable, EtsTable)) of
@@ -235,7 +244,9 @@ from_dets(EtsTable, DetsTable) ->
erlang:error(Unexpected,[EtsTable,DetsTable])
end.
--spec to_dets(tab(), dets:tab_name()) -> dets:tab_name().
+-spec to_dets(Tab, DetsTab) -> DetsTab when
+ Tab :: tab(),
+ DetsTab :: dets:tab_name().
to_dets(EtsTable, DetsTable) ->
case (catch dets:from_ets(DetsTable, EtsTable)) of
@@ -251,8 +262,11 @@ to_dets(EtsTable, DetsTable) ->
erlang:error(Unexpected,[EtsTable,DetsTable])
end.
--spec test_ms(tuple(), match_specs()) ->
- {'ok', term()} | {'error', [{'warning'|'error', string()}]}.
+-spec test_ms(Tuple, MatchSpec) -> {'ok', Result} | {'error', Errors} when
+ Tuple :: tuple(),
+ MatchSpec :: match_spec(),
+ Result :: term(),
+ Errors :: [{'warning'|'error', string()}].
test_ms(Term, MS) ->
case erlang:match_spec_test(Term, MS, table) of
@@ -262,7 +276,11 @@ test_ms(Term, MS) ->
Error
end.
--spec init_table(tab(), fun(('read' | 'close') -> term())) -> 'true'.
+-spec init_table(Tab, InitFun) -> 'true' when
+ Tab :: tab(),
+ InitFun :: fun((Arg) -> Res),
+ Arg :: 'read' | 'close',
+ Res :: 'end_of_input' | {Objects :: [term()], InitFun} | term().
init_table(Table, Fun) ->
ets:delete_all_objects(Table),
@@ -287,7 +305,9 @@ init_table_sub(Table, [H|T]) ->
ets:insert(Table, H),
init_table_sub(Table, T).
--spec match_delete(tab(), match_pattern()) -> 'true'.
+-spec match_delete(Tab, Pattern) -> 'true' when
+ Tab :: tab(),
+ Pattern :: match_pattern().
match_delete(Table, Pattern) ->
ets:select_delete(Table, [{Pattern,[],[true]}]),
@@ -295,7 +315,9 @@ match_delete(Table, Pattern) ->
%% Produce a list of tuples from a table
--spec tab2list(tab()) -> [tuple()].
+-spec tab2list(Tab) -> [Object] when
+ Tab :: tab(),
+ Object :: tuple().
tab2list(T) ->
ets:match_object(T, '_').
@@ -334,15 +356,21 @@ do_filter(Tab, Key, F, A, Ack) ->
md5sum = false :: boolean()
}).
--type fname() :: string() | atom().
--type t2f_option() :: {'extended_info', [ext_info()]}.
-
--spec tab2file(tab(), fname()) -> 'ok' | {'error', term()}.
+-spec tab2file(Tab, Filename) -> 'ok' | {'error', Reason} when
+ Tab :: tab(),
+ Filename :: file:name(),
+ Reason :: term().
tab2file(Tab, File) ->
tab2file(Tab, File, []).
--spec tab2file(tab(), fname(), [t2f_option()]) -> 'ok' | {'error', term()}.
+-spec tab2file(Tab, Filename, Options) -> 'ok' | {'error', Reason} when
+ Tab :: tab(),
+ Filename :: file:name(),
+ Options :: [Option],
+ Option :: {'extended_info', [ExtInfo]},
+ ExtInfo :: 'md5sum' | 'object_count',
+ Reason :: term().
tab2file(Tab, File, Options) ->
try
@@ -501,14 +529,20 @@ parse_ft_info_options(_,Malformed) ->
%% Opt := {verify,boolean()}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--type f2t_option() :: {'verify', boolean()}.
-
--spec file2tab(fname()) -> {'ok', tab()} | {'error', term()}.
+-spec file2tab(Filename) -> {'ok', Tab} | {'error', Reason} when
+ Filename :: file:name(),
+ Tab :: tab(),
+ Reason :: term().
file2tab(File) ->
file2tab(File, []).
--spec file2tab(fname(), [f2t_option()]) -> {'ok', tab()} | {'error', term()}.
+-spec file2tab(Filename, Options) -> {'ok', Tab} | {'error', Reason} when
+ Filename :: file:name(),
+ Tab :: tab(),
+ Options :: [Option],
+ Option :: {'verify', boolean()},
+ Reason :: term().
file2tab(File, Opts) ->
try
@@ -895,7 +929,22 @@ named_table(false) -> [].
%% information
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--spec tabfile_info(fname()) -> {'ok', [table_info()]} | {'error', term()}.
+-spec tabfile_info(Filename) -> {'ok', TableInfo} | {'error', Reason} when
+ Filename :: file:name(),
+ TableInfo :: [InfoItem],
+ InfoItem :: {'name', atom()}
+ | {'type', Type}
+ | {'protection', Protection}
+ | {'named_table', boolean()}
+ | {'keypos', non_neg_integer()}
+ | {'size', non_neg_integer()}
+ | {'extended_info', [ExtInfo]}
+ | {'version', {Major :: non_neg_integer(),
+ Minor :: non_neg_integer()}},
+ ExtInfo :: 'md5sum' | 'object_count',
+ Type :: 'bag' | 'duplicate_bag' | 'ordered_set' | 'set',
+ Protection :: 'private' | 'protected' | 'public',
+ Reason :: term().
tabfile_info(File) when is_list(File) ; is_atom(File) ->
try
@@ -932,20 +981,22 @@ tabfile_info(File) when is_list(File) ; is_atom(File) ->
{error,ExReason}
end.
--type qlc__query_handle() :: term(). %% XXX: belongs in 'qlc'
-
--type num_objects() :: 'default' | pos_integer().
--type trav_method() :: 'first_next' | 'last_prev'
- | 'select' | {'select', match_specs()}.
--type table_option() :: {'n_objects', num_objects()}
- | {'traverse', trav_method()}.
-
--spec table(tab()) -> qlc__query_handle().
+-spec table(Tab) -> QueryHandle when
+ Tab :: tab(),
+ QueryHandle :: qlc:query_handle().
table(Tab) ->
table(Tab, []).
--spec table(tab(), table_option() | [table_option()]) -> qlc__query_handle().
+-spec table(Tab, Options) -> QueryHandle when
+ Tab :: tab(),
+ QueryHandle :: qlc:query_handle(),
+ Options :: [Option] | Option,
+ Option :: {'n_objects', NObjects}
+ | {'traverse', TraverseMethod},
+ NObjects :: 'default' | pos_integer(),
+ TraverseMethod :: 'first_next' | 'last_prev'
+ | 'select' | {'select', MatchSpec :: match_spec()}.
table(Tab, Opts) ->
case options(Opts, [traverse, n_objects]) of
@@ -1135,7 +1186,8 @@ to_string(X) ->
lists:flatten(io_lib:format("~p", [X])).
%% view a specific table
--spec i(tab()) -> 'ok'.
+-spec i(Tab) -> 'ok' when
+ Tab :: tab().
i(Tab) ->
i(Tab, 40).
diff --git a/lib/stdlib/src/file_sorter.erl b/lib/stdlib/src/file_sorter.erl
index 2a5b08b581..3f31852afc 100644
--- a/lib/stdlib/src/file_sorter.erl
+++ b/lib/stdlib/src/file_sorter.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -50,12 +50,68 @@
%%% Exported functions
%%%
+-export_type([reason/0]).
+
+-type(file_name() :: file:name()).
+-type(file_names() :: [file:name()]).
+-type(i_command() :: read | close).
+-type(i_reply() :: end_of_input | {end_of_input, value()}
+ | {[object()], infun()} | input_reply()).
+-type(infun() :: fun((i_command()) -> i_reply())).
+-type(input() :: file_names() | infun()).
+-type(input_reply() :: term()).
+-type(o_command() :: {value, value()} | [object()] | close).
+-type(o_reply() :: outfun() | output_reply()).
+-type(object() :: term() | binary()).
+-type(outfun() :: fun((o_command()) -> o_reply())).
+-type(output() :: file_name() | outfun()).
+-type(output_reply() :: term()).
+-type(value() :: term()).
+
+-type(options() :: [option()] | option()).
+-type(option() :: {compressed, boolean()}
+ | {header, header_length()}
+ | {format, format()}
+ | {no_files, no_files()}
+ | {order, order()}
+ | {size, size()}
+ | {tmpdir, tmp_directory()}
+ | {unique, boolean()}).
+-type(format() :: binary_term | term | binary | format_fun()).
+-type(format_fun() :: fun((binary()) -> term())).
+-type(header_length() :: pos_integer()).
+-type(key_pos() :: pos_integer() | [pos_integer()]).
+-type(no_files() :: pos_integer()). % > 1
+-type(order() :: ascending | descending | order_fun()).
+-type(order_fun() :: fun((term(), term()) -> boolean())).
+-type(size() :: non_neg_integer()).
+-type(tmp_directory() :: [] | file:name()).
+
+-type(reason() :: bad_object
+ | {bad_object, file_name()}
+ | {bad_term, file_name()}
+ | {file_error, file_name(),
+ file:posix() | badarg | system_limit}
+ | {premature_eof, file_name()}).
+
+-spec(sort(FileName) -> Reply when
+ FileName :: file_name(),
+ Reply :: ok | {error, reason()} | input_reply() | output_reply()).
sort(FileName) ->
sort([FileName], FileName).
+-spec(sort(Input, Output) -> Reply when
+ Input :: input(),
+ Output :: output(),
+ Reply :: ok | {error, reason()} | input_reply() | output_reply()).
sort(Input, Output) ->
sort(Input, Output, []).
+-spec(sort(Input, Output, Options) -> Reply when
+ Input :: input(),
+ Output :: output(),
+ Options :: options(),
+ Reply :: ok | {error, reason()} | input_reply() | output_reply()).
sort(Input0, Output0, Options) ->
case {is_input(Input0), maybe_output(Output0), options(Options)} of
{{true,Input}, {true,Output}, #opts{}=Opts} ->
@@ -64,12 +120,27 @@ sort(Input0, Output0, Options) ->
badarg(culprit(tuple_to_list(T)), [Input0, Output0, Options])
end.
+-spec(keysort(KeyPos, FileName) -> Reply when
+ KeyPos :: key_pos(),
+ FileName :: file_name(),
+ Reply :: ok | {error, reason()} | input_reply() | output_reply()).
keysort(KeyPos, FileName) ->
keysort(KeyPos, [FileName], FileName).
+-spec(keysort(KeyPos, Input, Output) -> Reply when
+ KeyPos :: key_pos(),
+ Input :: input(),
+ Output :: output(),
+ Reply :: ok | {error, reason()} | input_reply() | output_reply()).
keysort(KeyPos, Input, Output) ->
keysort(KeyPos, Input, Output, []).
+-spec(keysort(KeyPos, Input, Output, Options) -> Reply when
+ KeyPos :: key_pos(),
+ Input :: input(),
+ Output :: output(),
+ Options :: options(),
+ Reply :: ok | {error, reason()} | input_reply() | output_reply()).
keysort(KeyPos, Input0, Output0, Options) ->
R = case {is_keypos(KeyPos), is_input(Input0),
maybe_output(Output0), options(Options)} of
@@ -89,9 +160,18 @@ keysort(KeyPos, Input0, Output0, Options) ->
badarg(culprit(O), [KeyPos, Input0, Output0, Options])
end.
+-spec(merge(FileNames, Output) -> Reply when
+ FileNames :: file_names(),
+ Output :: output(),
+ Reply :: ok | {error, reason()} | output_reply()).
merge(Files, Output) ->
merge(Files, Output, []).
+-spec(merge(FileNames, Output, Options) -> Reply when
+ FileNames :: file_names(),
+ Output :: output(),
+ Options :: options(),
+ Reply :: ok | {error, reason()} | output_reply()).
merge(Files0, Output0, Options) ->
case {is_files(Files0), maybe_output(Output0), options(Options)} of
%% size not used
@@ -101,9 +181,20 @@ merge(Files0, Output0, Options) ->
badarg(culprit(tuple_to_list(T)), [Files0, Output0, Options])
end.
+-spec(keymerge(KeyPos, FileNames, Output) -> Reply when
+ KeyPos :: key_pos(),
+ FileNames :: file_names(),
+ Output :: output(),
+ Reply :: ok | {error, reason()} | output_reply()).
keymerge(KeyPos, Files, Output) ->
keymerge(KeyPos, Files, Output, []).
+-spec(keymerge(KeyPos, FileNames, Output, Options) -> Reply when
+ KeyPos :: key_pos(),
+ FileNames :: file_names(),
+ Output :: output(),
+ Options :: options(),
+ Reply :: ok | {error, reason()} | output_reply()).
keymerge(KeyPos, Files0, Output0, Options) ->
R = case {is_keypos(KeyPos), is_files(Files0),
maybe_output(Output0), options(Options)} of
@@ -123,9 +214,21 @@ keymerge(KeyPos, Files0, Output0, Options) ->
badarg(culprit(O), [KeyPos, Files0, Output0, Options])
end.
+-spec(check(FileName) -> Reply when
+ FileName :: file_name(),
+ Reply :: {ok, [Result]} | {error, reason()},
+ Result :: {FileName, TermPosition, term()},
+ TermPosition :: pos_integer()).
check(FileName) ->
check([FileName], []).
+-spec(check(FileNames, Options) -> Reply when
+ FileNames :: file_names(),
+ Options :: options(),
+ Reply :: {ok, [Result]} | {error, reason()},
+ Result :: {FileName, TermPosition, term()},
+ FileName :: file_name(),
+ TermPosition :: pos_integer()).
check(Files0, Options) ->
case {is_files(Files0), options(Options)} of
{{true,Files}, #opts{}=Opts} ->
@@ -134,9 +237,23 @@ check(Files0, Options) ->
badarg(culprit(tuple_to_list(T)), [Files0, Options])
end.
+-spec(keycheck(KeyPos, FileName) -> Reply when
+ KeyPos :: key_pos(),
+ FileName :: file_name(),
+ Reply :: {ok, [Result]} | {error, reason()},
+ Result :: {FileName, TermPosition, term()},
+ TermPosition :: pos_integer()).
keycheck(KeyPos, FileName) ->
keycheck(KeyPos, [FileName], []).
+-spec(keycheck(KeyPos, FileNames, Options) -> Reply when
+ KeyPos :: key_pos(),
+ FileNames :: file_names(),
+ Options :: options(),
+ Reply :: {ok, [Result]} | {error, reason()},
+ Result :: {FileName, TermPosition, term()},
+ FileName :: file_name(),
+ TermPosition :: pos_integer()).
keycheck(KeyPos, Files0, Options) ->
R = case {is_keypos(KeyPos), is_files(Files0), options(Options)} of
{_, _, #opts{format = binary}} ->
diff --git a/lib/stdlib/src/filelib.erl b/lib/stdlib/src/filelib.erl
index c845b61204..d532cea187 100644
--- a/lib/stdlib/src/filelib.erl
+++ b/lib/stdlib/src/filelib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -40,13 +40,19 @@
erlang:error(UnUsUalVaRiAbLeNaMe)
end).
+-type filename() :: file:name().
+-type dirname() :: filename().
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--spec wildcard(file:name()) -> [file:filename()].
+-spec wildcard(Wildcard) -> [file:filename()] when
+ Wildcard :: filename() | dirname().
wildcard(Pattern) when is_list(Pattern) ->
?HANDLE_ERROR(do_wildcard(Pattern, file)).
--spec wildcard(file:name(), file:name() | atom()) -> [file:filename()].
+-spec wildcard(Wildcard, Cwd) -> [file:filename()] when
+ Wildcard :: filename() | dirname(),
+ Cwd :: dirname().
wildcard(Pattern, Cwd) when is_list(Pattern), (is_list(Cwd) or is_binary(Cwd)) ->
?HANDLE_ERROR(do_wildcard(Pattern, Cwd, file));
wildcard(Pattern, Mod) when is_list(Pattern), is_atom(Mod) ->
@@ -57,7 +63,8 @@ wildcard(Pattern, Cwd, Mod)
when is_list(Pattern), (is_list(Cwd) or is_binary(Cwd)), is_atom(Mod) ->
?HANDLE_ERROR(do_wildcard(Pattern, Cwd, Mod)).
--spec is_dir(file:name()) -> boolean().
+-spec is_dir(Name) -> boolean() when
+ Name :: filename() | dirname().
is_dir(Dir) ->
do_is_dir(Dir, file).
@@ -65,7 +72,8 @@ is_dir(Dir) ->
is_dir(Dir, Mod) when is_atom(Mod) ->
do_is_dir(Dir, Mod).
--spec is_file(file:name()) -> boolean().
+-spec is_file(Name) -> boolean() when
+ Name :: filename() | dirname().
is_file(File) ->
do_is_file(File, file).
@@ -73,7 +81,8 @@ is_file(File) ->
is_file(File, Mod) when is_atom(Mod) ->
do_is_file(File, Mod).
--spec is_regular(file:name()) -> boolean().
+-spec is_regular(Name) -> boolean() when
+ Name :: filename().
is_regular(File) ->
do_is_regular(File, file).
@@ -81,7 +90,13 @@ is_regular(File) ->
is_regular(File, Mod) when is_atom(Mod) ->
do_is_regular(File, Mod).
--spec fold_files(file:name(), string(), boolean(), fun((_,_) -> _), _) -> _.
+-spec fold_files(Dir, RegExp, Recursive, Fun, AccIn) -> AccOut when
+ Dir :: dirname(),
+ RegExp :: string(),
+ Recursive :: boolean(),
+ Fun :: fun((F :: file:filename(), AccIn) -> AccOut),
+ AccIn :: term(),
+ AccOut :: term().
fold_files(Dir, RegExp, Recursive, Fun, Acc) ->
do_fold_files(Dir, RegExp, Recursive, Fun, Acc, file).
@@ -89,7 +104,8 @@ fold_files(Dir, RegExp, Recursive, Fun, Acc) ->
fold_files(Dir, RegExp, Recursive, Fun, Acc, Mod) when is_atom(Mod) ->
do_fold_files(Dir, RegExp, Recursive, Fun, Acc, Mod).
--spec last_modified(file:name()) -> file:date_time() | 0.
+-spec last_modified(Name) -> file:date_time() | 0 when
+ Name :: filename() | dirname().
last_modified(File) ->
do_last_modified(File, file).
@@ -97,7 +113,8 @@ last_modified(File) ->
last_modified(File, Mod) when is_atom(Mod) ->
do_last_modified(File, Mod).
--spec file_size(file:name()) -> non_neg_integer().
+-spec file_size(Filename) -> non_neg_integer() when
+ Filename :: filename().
file_size(File) ->
do_file_size(File, file).
@@ -237,7 +254,9 @@ do_file_size(File, Mod) ->
%% +type X = filename() | dirname()
%% ensures that the directory name required to create D exists
--spec ensure_dir(file:name()) -> 'ok' | {'error', file:posix()}.
+-spec ensure_dir(Name) -> 'ok' | {'error', Reason} when
+ Name :: filename() | dirname(),
+ Reason :: file:posix().
ensure_dir("/") ->
ok;
ensure_dir(F) ->
diff --git a/lib/stdlib/src/filename.erl b/lib/stdlib/src/filename.erl
index 24abf1e977..1cb9e4a25e 100644
--- a/lib/stdlib/src/filename.erl
+++ b/lib/stdlib/src/filename.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -61,12 +61,15 @@
%% (for WIN32): absname("/") -> "D:/"
--spec absname(file:name()) -> file:filename().
+-spec absname(Filename) -> file:filename() when
+ Filename :: file:name().
absname(Name) ->
{ok, Cwd} = file:get_cwd(),
absname(Name, Cwd).
--spec absname(file:name(), file:filename()) -> file:filename().
+-spec absname(Filename, Dir) -> file:filename() when
+ Filename :: file:name(),
+ Dir :: file:filename().
absname(Name, AbsBase) when is_binary(Name), is_list(AbsBase) ->
absname(Name,filename_string_to_binary(AbsBase));
absname(Name, AbsBase) when is_list(Name), is_binary(AbsBase) ->
@@ -119,7 +122,9 @@ absname_vr([[X, $:]|Name], _, _AbsBase) ->
%% This is just a join/2, but assumes that
%% AbsBase must be absolute and Name must be relative.
--spec absname_join(file:filename(), file:name()) -> file:filename().
+-spec absname_join(Dir, Filename) -> file:filename() when
+ Dir :: file:filename(),
+ Filename :: file:name().
absname_join(AbsBase, Name) ->
join(AbsBase, flatten(Name)).
@@ -131,7 +136,8 @@ absname_join(AbsBase, Name) ->
%% basename("/usr/foo/") -> "foo" (trailing slashes ignored)
%% basename("/") -> []
--spec basename(file:name()) -> file:filename().
+-spec basename(Filename) -> file:filename() when
+ Filename :: file:name().
basename(Name) when is_binary(Name) ->
case os:type() of
{win32,_} ->
@@ -192,7 +198,9 @@ skip_prefix(Name, _) ->
%% rootname(basename("xxx.jam")) -> "xxx"
%% rootname(basename("xxx.erl")) -> "xxx"
--spec basename(file:name(), file:name()) -> file:filename().
+-spec basename(Filename, Ext) -> file:filename() when
+ Filename :: file:name(),
+ Ext :: file:name().
basename(Name, Ext) when is_binary(Name), is_list(Ext) ->
basename(Name,filename_string_to_binary(Ext));
basename(Name, Ext) when is_list(Name), is_binary(Ext) ->
@@ -240,7 +248,8 @@ basename([], _Ext, Tail, _DrvSep2) ->
%% Example: dirname("/usr/src/kalle.erl") -> "/usr/src",
%% dirname("kalle.erl") -> "."
--spec dirname(file:name()) -> file:filename().
+-spec dirname(Filename) -> file:filename() when
+ Filename :: file:name().
dirname(Name) when is_binary(Name) ->
{Dsep,Drivesep} = separators(),
SList = case Dsep of
@@ -332,7 +341,8 @@ dirjoin1([H|T],Acc,Sep) ->
%%
%% On Windows: fn:dirname("\\usr\\src/kalle.erl") -> "/usr/src"
--spec extension(file:name()) -> file:filename().
+-spec extension(Filename) -> file:filename() when
+ Filename :: file:name().
extension(Name) when is_binary(Name) ->
{Dsep,_} = separators(),
SList = case Dsep of
@@ -374,7 +384,8 @@ extension([], Result, _OsType) ->
%% Joins a list of filenames with directory separators.
--spec join([file:filename()]) -> file:filename().
+-spec join(Components) -> file:filename() when
+ Components :: [file:filename()].
join([Name1, Name2|Rest]) ->
join([join(Name1, Name2)|Rest]);
join([Name]) when is_list(Name) ->
@@ -386,7 +397,9 @@ join([Name]) when is_atom(Name) ->
%% Joins two filenames with directory separators.
--spec join(file:filename(), file:filename()) -> file:filename().
+-spec join(Name1, Name2) -> file:filename() when
+ Name1 :: file:filename(),
+ Name2 :: file:filename().
join(Name1, Name2) when is_list(Name1), is_list(Name2) ->
OsType = major_os_type(),
case pathtype(Name2) of
@@ -494,7 +507,8 @@ append(Dir, Name) ->
%% current working volume. (Windows only)
%% Example: a:bar.erl, /temp/foo.erl
--spec pathtype(file:name()) -> 'absolute' | 'relative' | 'volumerelative'.
+-spec pathtype(Path) -> 'absolute' | 'relative' | 'volumerelative' when
+ Path :: file:name().
pathtype(Atom) when is_atom(Atom) ->
pathtype(atom_to_list(Atom));
pathtype(Name) when is_list(Name) or is_binary(Name) ->
@@ -547,7 +561,8 @@ win32_pathtype(_) -> relative.
%% Examples: rootname("/jam.src/kalle") -> "/jam.src/kalle"
%% rootname("/jam.src/foo.erl") -> "/jam.src/foo"
--spec rootname(file:name()) -> file:filename().
+-spec rootname(Filename) -> file:filename() when
+ Filename :: file:name().
rootname(Name) when is_binary(Name) ->
list_to_binary(rootname(binary_to_list(Name))); % No need to handle unicode, . is < 128
rootname(Name0) ->
@@ -576,7 +591,9 @@ rootname([], Root, _Ext, _OsType) ->
%% Examples: rootname("/jam.src/kalle.jam", ".erl") -> "/jam.src/kalle.jam"
%% rootname("/jam.src/foo.erl", ".erl") -> "/jam.src/foo"
--spec rootname(file:name(), file:name()) -> file:filename().
+-spec rootname(Filename, Ext) -> file:filename() when
+ Filename :: file:name(),
+ Ext :: file:name().
rootname(Name, Ext) when is_binary(Name), is_binary(Ext) ->
list_to_binary(rootname(binary_to_list(Name),binary_to_list(Ext)));
rootname(Name, Ext) when is_binary(Name) ->
@@ -602,7 +619,9 @@ rootname2([Char|Rest], Ext, Result) when is_integer(Char) ->
%% split("foo/bar") -> ["foo", "bar"]
%% split("a:\\msdev\\include") -> ["a:/", "msdev", "include"]
--spec split(file:name()) -> [file:filename()].
+-spec split(Filename) -> Components when
+ Filename :: file:name(),
+ Components :: [file:filename()].
split(Name) when is_binary(Name) ->
case os:type() of
{win32, _} -> win32_splitb(Name);
@@ -695,7 +714,8 @@ split([], Comp, Components, OsType) ->
%% will be converted to backslashes. On all platforms, the
%% name will be normalized as done by join/1.
--spec nativename(file:filename()) -> file:filename().
+-spec nativename(Path) -> file:filename() when
+ Path :: file:filename().
nativename(Name0) ->
Name = join([Name0]), %Normalize.
case os:type() of
@@ -747,12 +767,17 @@ separators() ->
%% The paths in the {outdir, Path} and {i, Path} options are guaranteed
%% to be absolute.
--type rule() :: {string(), string()}.
--type ecode() :: 'non_existing' | 'preloaded' | 'interpreted'.
--type option() :: {'i', string()} | {'outdir', string()} | {'d', atom()}.
-
--spec find_src(atom() | string()) ->
- {string(), [option()]} | {'error', {ecode(), atom()}}.
+-spec find_src(Beam) -> {SourceFile, Options}
+ | {error, {ErrorReason, Module}} when
+ Beam :: Module | Filename,
+ Filename :: atom() | string(),
+ Module :: module(),
+ SourceFile :: string(),
+ Options :: [Option],
+ Option :: {'i', Path :: string()}
+ | {'outdir', Path :: string()}
+ | {'d', atom()},
+ ErrorReason :: 'non_existing' | 'preloaded' | 'interpreted'.
find_src(Mod) ->
Default = [{"", ""}, {"ebin", "src"}, {"ebin", "esrc"}],
Rules =
@@ -763,8 +788,18 @@ find_src(Mod) ->
end,
find_src(Mod, Rules).
--spec find_src(atom() | string(), [rule()]) ->
- {string(), [option()]} | {'error', {ecode(), atom()}}.
+-spec find_src(Beam, Rules) -> {SourceFile, Options}
+ | {error, {ErrorReason, Module}} when
+ Beam :: Module | Filename,
+ Filename :: atom() | string(),
+ Rules :: [{BinSuffix :: string(), SourceSuffix :: string()}],
+ Module :: module(),
+ SourceFile :: string(),
+ Options :: [Option],
+ Option :: {'i', Path :: string()}
+ | {'outdir', Path :: string()}
+ | {'d', atom()},
+ ErrorReason :: 'non_existing' | 'preloaded' | 'interpreted'.
find_src(Mod, Rules) when is_atom(Mod) ->
find_src(atom_to_list(Mod), Rules);
find_src(File0, Rules) when is_list(File0) ->
@@ -890,7 +925,8 @@ major_os_type() ->
%% flatten(List)
%% Flatten a list, also accepting atoms.
--spec flatten(file:name()) -> file:filename().
+-spec flatten(Filename) -> file:filename() when
+ Filename :: file:name().
flatten(Bin) when is_binary(Bin) ->
Bin;
flatten(List) ->
diff --git a/lib/stdlib/src/gb_sets.erl b/lib/stdlib/src/gb_sets.erl
index fc5beb28b0..91d21d869c 100644
--- a/lib/stdlib/src/gb_sets.erl
+++ b/lib/stdlib/src/gb_sets.erl
@@ -197,6 +197,7 @@
%% Some types.
-type gb_set_node() :: 'nil' | {term(), _, _}.
+-opaque iter() :: [gb_set_node()].
%% A declaration equivalent to the following is currently hard-coded
%% in erl_types.erl
@@ -205,38 +206,47 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--spec empty() -> gb_set().
+-spec empty() -> Set when
+ Set :: gb_set().
empty() ->
{0, nil}.
--spec new() -> gb_set().
+-spec new() -> Set when
+ Set :: gb_set().
new() -> empty().
--spec is_empty(gb_set()) -> boolean().
+-spec is_empty(Set) -> boolean() when
+ Set :: gb_set().
is_empty({0, nil}) ->
true;
is_empty(_) ->
false.
--spec size(gb_set()) -> non_neg_integer().
+-spec size(Set) -> non_neg_integer() when
+ Set :: gb_set().
size({Size, _}) ->
Size.
--spec singleton(term()) -> gb_set().
+-spec singleton(Element) -> gb_set() when
+ Element :: term().
singleton(Key) ->
{1, {Key, nil, nil}}.
--spec is_element(term(), gb_set()) -> boolean().
+-spec is_element(Element, Set) -> boolean() when
+ Element :: term(),
+ Set :: gb_set().
is_element(Key, S) ->
is_member(Key, S).
--spec is_member(term(), gb_set()) -> boolean().
+-spec is_member(Element, Set) -> boolean() when
+ Element :: term(),
+ Set :: gb_set().
is_member(Key, {_, T}) ->
is_member_1(Key, T).
@@ -250,7 +260,10 @@ is_member_1(_, {_, _, _}) ->
is_member_1(_, nil) ->
false.
--spec insert(term(), gb_set()) -> gb_set().
+-spec insert(Element, Set1) -> Set2 when
+ Element :: term(),
+ Set1 :: gb_set(),
+ Set2 :: gb_set().
insert(Key, {S, T}) ->
S1 = S + 1,
@@ -306,7 +319,9 @@ count({_, Sm, Bi}) ->
count(nil) ->
{1, 0}.
--spec balance(gb_set()) -> gb_set().
+-spec balance(Set1) -> Set2 when
+ Set1 :: gb_set(),
+ Set2 :: gb_set().
balance({S, T}) ->
{S, balance(T, S)}.
@@ -331,12 +346,18 @@ balance_list_1([Key | L], 1) ->
balance_list_1(L, 0) ->
{nil, L}.
--spec add_element(term(), gb_set()) -> gb_set().
+-spec add_element(Element, Set1) -> Set2 when
+ Element :: term(),
+ Set1 :: gb_set(),
+ Set2 :: gb_set().
add_element(X, S) ->
add(X, S).
--spec add(term(), gb_set()) -> gb_set().
+-spec add(Element, Set1) -> Set2 when
+ Element :: term(),
+ Set1 :: gb_set(),
+ Set2 :: gb_set().
add(X, S) ->
case is_member(X, S) of
@@ -346,23 +367,33 @@ add(X, S) ->
insert(X, S)
end.
--spec from_list([term()]) -> gb_set().
+-spec from_list(List) -> Set when
+ List :: [term()],
+ Set :: gb_set().
from_list(L) ->
from_ordset(ordsets:from_list(L)).
--spec from_ordset([term()]) -> gb_set().
+-spec from_ordset(List) -> Set when
+ List :: [term()],
+ Set :: gb_set().
from_ordset(L) ->
S = length(L),
{S, balance_list(L, S)}.
--spec del_element(term(), gb_set()) -> gb_set().
+-spec del_element(Element, Set1) -> Set2 when
+ Element :: term(),
+ Set1 :: gb_set(),
+ Set2 :: gb_set().
del_element(Key, S) ->
delete_any(Key, S).
--spec delete_any(term(), gb_set()) -> gb_set().
+-spec delete_any(Element, Set1) -> Set2 when
+ Element :: term(),
+ Set1 :: gb_set(),
+ Set2 :: gb_set().
delete_any(Key, S) ->
case is_member(Key, S) of
@@ -372,7 +403,10 @@ delete_any(Key, S) ->
S
end.
--spec delete(term(), gb_set()) -> gb_set().
+-spec delete(Element, Set1) -> Set2 when
+ Element :: term(),
+ Set1 :: gb_set(),
+ Set2 :: gb_set().
delete(Key, {S, T}) ->
{S - 1, delete_1(Key, T)}.
@@ -394,7 +428,10 @@ merge(Smaller, Larger) ->
{Key, Larger1} = take_smallest1(Larger),
{Key, Smaller, Larger1}.
--spec take_smallest(gb_set()) -> {term(), gb_set()}.
+-spec take_smallest(Set1) -> {Element, Set2} when
+ Set1 :: gb_set(),
+ Set2 :: gb_set(),
+ Element :: term().
take_smallest({S, T}) ->
{Key, Larger} = take_smallest1(T),
@@ -406,7 +443,8 @@ take_smallest1({Key, Smaller, Larger}) ->
{Key1, Smaller1} = take_smallest1(Smaller),
{Key1, {Key, Smaller1, Larger}}.
--spec smallest(gb_set()) -> term().
+-spec smallest(Set) -> term() when
+ Set :: gb_set().
smallest({_, T}) ->
smallest_1(T).
@@ -416,7 +454,10 @@ smallest_1({Key, nil, _Larger}) ->
smallest_1({_Key, Smaller, _Larger}) ->
smallest_1(Smaller).
--spec take_largest(gb_set()) -> {term(), gb_set()}.
+-spec take_largest(Set1) -> {Element, Set2} when
+ Set1 :: gb_set(),
+ Set2 :: gb_set(),
+ Element :: term().
take_largest({S, T}) ->
{Key, Smaller} = take_largest1(T),
@@ -428,7 +469,8 @@ take_largest1({Key, Smaller, Larger}) ->
{Key1, Larger1} = take_largest1(Larger),
{Key1, {Key, Smaller, Larger1}}.
--spec largest(gb_set()) -> term().
+-spec largest(Set) -> term() when
+ Set :: gb_set().
largest({_, T}) ->
largest_1(T).
@@ -438,7 +480,9 @@ largest_1({Key, _Smaller, nil}) ->
largest_1({_Key, _Smaller, Larger}) ->
largest_1(Larger).
--spec to_list(gb_set()) -> [term()].
+-spec to_list(Set) -> List when
+ Set :: gb_set(),
+ List :: [term()].
to_list({_, T}) ->
to_list(T, []).
@@ -449,7 +493,9 @@ to_list({Key, Small, Big}, L) ->
to_list(Small, [Key | to_list(Big, L)]);
to_list(nil, L) -> L.
--spec iterator(gb_set()) -> [term()].
+-spec iterator(Set) -> Iter when
+ Set :: gb_set(),
+ Iter :: iter().
iterator({_, T}) ->
iterator(T, []).
@@ -464,7 +510,10 @@ iterator({_, L, _} = T, As) ->
iterator(nil, As) ->
As.
--spec next([term()]) -> {term(), [term()]} | 'none'.
+-spec next(Iter1) -> {Element, Iter2} | 'none' when
+ Iter1 :: iter(),
+ Iter2 :: iter(),
+ Element :: term().
next([{X, _, T} | As]) ->
{X, iterator(T, As)};
@@ -494,7 +543,10 @@ next([]) ->
%% traversing the elements can be devised, but they all have higher
%% overhead.
--spec union(gb_set(), gb_set()) -> gb_set().
+-spec union(Set1, Set2) -> Set3 when
+ Set1 :: gb_set(),
+ Set2 :: gb_set(),
+ Set3 :: gb_set().
union({N1, T1}, {N2, T2}) when N2 < N1 ->
union(to_list_1(T2), N2, T1, N1);
@@ -596,7 +648,9 @@ balance_revlist_1([Key | L], 1) ->
balance_revlist_1(L, 0) ->
{nil, L}.
--spec union([gb_set()]) -> gb_set().
+-spec union(SetList) -> Set when
+ SetList :: [gb_set(),...],
+ Set :: gb_set().
union([S | Ss]) ->
union_list(S, Ss);
@@ -609,7 +663,10 @@ union_list(S, []) -> S.
%% The rest is modelled on the above.
--spec intersection(gb_set(), gb_set()) -> gb_set().
+-spec intersection(Set1, Set2) -> Set3 when
+ Set1 :: gb_set(),
+ Set2 :: gb_set(),
+ Set3 :: gb_set().
intersection({N1, T1}, {N2, T2}) when N2 < N1 ->
intersection(to_list_1(T2), N2, T1, N1);
@@ -657,7 +714,9 @@ intersection_2([], _, As, S) ->
intersection_2(_, [], As, S) ->
{S, balance_revlist(As, S)}.
--spec intersection([gb_set(),...]) -> gb_set().
+-spec intersection(SetList) -> Set when
+ SetList :: [gb_set(),...],
+ Set :: gb_set().
intersection([S | Ss]) ->
intersection_list(S, Ss).
@@ -666,7 +725,9 @@ intersection_list(S, [S1 | Ss]) ->
intersection_list(intersection(S, S1), Ss);
intersection_list(S, []) -> S.
--spec is_disjoint(gb_set(), gb_set()) -> boolean().
+-spec is_disjoint(Set1, Set2) -> boolean() when
+ Set1 :: gb_set(),
+ Set2 :: gb_set().
is_disjoint({N1, T1}, {N2, T2}) when N1 < N2 ->
is_disjoint_1(T1, T2);
@@ -694,12 +755,18 @@ is_disjoint_1(_, nil) ->
%% the sets. Therefore, we always build a new tree, and thus we need to
%% traverse the whole element list of the left operand.
--spec subtract(gb_set(), gb_set()) -> gb_set().
+-spec subtract(Set1, Set2) -> Set3 when
+ Set1 :: gb_set(),
+ Set2 :: gb_set(),
+ Set3 :: gb_set().
subtract(S1, S2) ->
difference(S1, S2).
--spec difference(gb_set(), gb_set()) -> gb_set().
+-spec difference(Set1, Set2) -> Set3 when
+ Set1 :: gb_set(),
+ Set2 :: gb_set(),
+ Set3 :: gb_set().
difference({N1, T1}, {N2, T2}) ->
difference(to_list_1(T1), N1, T2, N2).
@@ -747,7 +814,9 @@ difference_2(Xs, [], As, S) ->
%% Subset testing is much the same thing as set difference, but
%% without the construction of a new set.
--spec is_subset(gb_set(), gb_set()) -> boolean().
+-spec is_subset(Set1, Set2) -> boolean() when
+ Set1 :: gb_set(),
+ Set2 :: gb_set().
is_subset({N1, T1}, {N2, T2}) ->
is_subset(to_list_1(T1), N1, T2, N2).
@@ -788,18 +857,28 @@ is_subset_2(_, []) ->
%% For compatibility with `sets':
--spec is_set(term()) -> boolean().
+-spec is_set(Term) -> boolean() when
+ Term :: term().
is_set({0, nil}) -> true;
is_set({N, {_, _, _}}) when is_integer(N), N >= 0 -> true;
is_set(_) -> false.
--spec filter(fun((term()) -> boolean()), gb_set()) -> gb_set().
+-spec filter(Pred, Set1) -> Set2 when
+ Pred :: fun((E :: term()) -> boolean()),
+ Set1 :: gb_set(),
+ Set2 :: gb_set().
filter(F, S) ->
from_ordset([X || X <- to_list(S), F(X)]).
--spec fold(fun((term(), term()) -> term()), term(), gb_set()) -> term().
+-spec fold(Function, Acc0, Set) -> Acc1 when
+ Function :: fun((E :: term(), AccIn) -> AccOut),
+ Acc0 :: term(),
+ Acc1 :: term(),
+ AccIn :: term(),
+ AccOut :: term(),
+ Set :: gb_set().
fold(F, A, {_, T}) when is_function(F, 2) ->
fold_1(F, A, T).
diff --git a/lib/stdlib/src/gb_trees.erl b/lib/stdlib/src/gb_trees.erl
index d37786a100..6ad861ff5b 100644
--- a/lib/stdlib/src/gb_trees.erl
+++ b/lib/stdlib/src/gb_trees.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -153,6 +153,7 @@
%% Some types.
-type gb_tree_node() :: 'nil' | {_, _, _, _}.
+-opaque iter() :: [gb_tree_node()].
%% A declaration equivalent to the following is currently hard-coded
%% in erl_types.erl
@@ -166,21 +167,26 @@
empty() ->
{0, nil}.
--spec is_empty(gb_tree()) -> boolean().
+-spec is_empty(Tree) -> boolean() when
+ Tree :: gb_tree().
is_empty({0, nil}) ->
true;
is_empty(_) ->
false.
--spec size(gb_tree()) -> non_neg_integer().
+-spec size(Tree) -> non_neg_integer() when
+ Tree :: gb_tree().
size({Size, _}) when is_integer(Size), Size >= 0 ->
Size.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--spec lookup(term(), gb_tree()) -> 'none' | {'value', term()}.
+-spec lookup(Key, Tree) -> 'none' | {'value', Val} when
+ Key :: term(),
+ Val :: term(),
+ Tree :: gb_tree().
lookup(Key, {_, T}) ->
lookup_1(Key, T).
@@ -205,7 +211,9 @@ lookup_1(_, nil) ->
%% This is a specialized version of `lookup'.
--spec is_defined(term(), gb_tree()) -> boolean().
+-spec is_defined(Key, Tree) -> boolean() when
+ Key :: term(),
+ Tree :: gb_tree().
is_defined(Key, {_, T}) ->
is_defined_1(Key, T).
@@ -223,7 +231,10 @@ is_defined_1(_, nil) ->
%% This is a specialized version of `lookup'.
--spec get(term(), gb_tree()) -> term().
+-spec get(Key, Tree) -> Val when
+ Key :: term(),
+ Tree :: gb_tree(),
+ Val :: term().
get(Key, {_, T}) ->
get_1(Key, T).
@@ -237,7 +248,11 @@ get_1(_, {_, Value, _, _}) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--spec update(term(), term(), gb_tree()) -> gb_tree().
+-spec update(Key, Val, Tree1) -> Tree2 when
+ Key :: term(),
+ Val :: term(),
+ Tree1 :: gb_tree(),
+ Tree2 :: gb_tree().
update(Key, Val, {S, T}) ->
T1 = update_1(Key, Val, T),
@@ -254,7 +269,11 @@ update_1(Key, Value, {_, _, Smaller, Bigger}) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--spec insert(term(), term(), gb_tree()) -> gb_tree().
+-spec insert(Key, Val, Tree1) -> Tree2 when
+ Key :: term(),
+ Val :: term(),
+ Tree1 :: gb_tree(),
+ Tree2 :: gb_tree().
insert(Key, Val, {S, T}) when is_integer(S) ->
S1 = S+1,
@@ -303,7 +322,11 @@ insert_1(Key, _, _, _) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--spec enter(term(), term(), gb_tree()) -> gb_tree().
+-spec enter(Key, Val, Tree1) -> Tree2 when
+ Key :: term(),
+ Val :: term(),
+ Tree1 :: gb_tree(),
+ Tree2 :: gb_tree().
enter(Key, Val, T) ->
case is_defined(Key, T) of
@@ -326,7 +349,9 @@ count(nil) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--spec balance(gb_tree()) -> gb_tree().
+-spec balance(Tree1) -> Tree2 when
+ Tree1 :: gb_tree(),
+ Tree2 :: gb_tree().
balance({S, T}) ->
{S, balance(T, S)}.
@@ -351,7 +376,9 @@ balance_list_1([{Key, Val} | L], 1) ->
balance_list_1(L, 0) ->
{nil, L}.
--spec from_orddict([{_,_}]) -> gb_tree().
+-spec from_orddict(List) -> Tree when
+ List :: [{Key :: term(), Val :: term()}],
+ Tree :: gb_tree().
from_orddict(L) ->
S = length(L),
@@ -359,7 +386,10 @@ from_orddict(L) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--spec delete_any(term(), gb_tree()) -> gb_tree().
+-spec delete_any(Key, Tree1) -> Tree2 when
+ Key :: term(),
+ Tree1 :: gb_tree(),
+ Tree2 :: gb_tree().
delete_any(Key, T) ->
case is_defined(Key, T) of
@@ -371,7 +401,10 @@ delete_any(Key, T) ->
%%% delete. Assumes that key is present.
--spec delete(term(), gb_tree()) -> gb_tree().
+-spec delete(Key, Tree1) -> Tree2 when
+ Key :: term(),
+ Tree1 :: gb_tree(),
+ Tree2 :: gb_tree().
delete(Key, {S, T}) when is_integer(S), S >= 0 ->
{S - 1, delete_1(Key, T)}.
@@ -397,7 +430,11 @@ merge(Smaller, Larger) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--spec take_smallest(gb_tree()) -> {term(), term(), gb_tree()}.
+-spec take_smallest(Tree1) -> {Key, Val, Tree2} when
+ Tree1 :: gb_tree(),
+ Tree2 :: gb_tree(),
+ Key :: term(),
+ Val :: term().
take_smallest({Size, Tree}) when is_integer(Size), Size >= 0 ->
{Key, Value, Larger} = take_smallest1(Tree),
@@ -409,7 +446,10 @@ take_smallest1({Key, Value, Smaller, Larger}) ->
{Key1, Value1, Smaller1} = take_smallest1(Smaller),
{Key1, Value1, {Key, Value, Smaller1, Larger}}.
--spec smallest(gb_tree()) -> {term(), term()}.
+-spec smallest(Tree) -> {Key, Val} when
+ Tree :: gb_tree(),
+ Key :: term(),
+ Val :: term().
smallest({_, Tree}) ->
smallest_1(Tree).
@@ -419,7 +459,11 @@ smallest_1({Key, Value, nil, _Larger}) ->
smallest_1({_Key, _Value, Smaller, _Larger}) ->
smallest_1(Smaller).
--spec take_largest(gb_tree()) -> {term(), term(), gb_tree()}.
+-spec take_largest(Tree1) -> {Key, Val, Tree2} when
+ Tree1 :: gb_tree(),
+ Tree2 :: gb_tree(),
+ Key :: term(),
+ Val :: term().
take_largest({Size, Tree}) when is_integer(Size), Size >= 0 ->
{Key, Value, Smaller} = take_largest1(Tree),
@@ -431,7 +475,10 @@ take_largest1({Key, Value, Smaller, Larger}) ->
{Key1, Value1, Larger1} = take_largest1(Larger),
{Key1, Value1, {Key, Value, Smaller, Larger1}}.
--spec largest(gb_tree()) -> {term(), term()}.
+-spec largest(Tree) -> {Key, Val} when
+ Tree :: gb_tree(),
+ Key :: term(),
+ Val :: term().
largest({_, Tree}) ->
largest_1(Tree).
@@ -443,7 +490,10 @@ largest_1({_Key, _Value, _Smaller, Larger}) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--spec to_list(gb_tree()) -> [{term(), term()}].
+-spec to_list(Tree) -> [{Key, Val}] when
+ Tree :: gb_tree(),
+ Key :: term(),
+ Val :: term().
to_list({_, T}) ->
to_list(T, []).
@@ -456,7 +506,9 @@ to_list(nil, L) -> L.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--spec keys(gb_tree()) -> [term()].
+-spec keys(Tree) -> [Key] when
+ Tree :: gb_tree(),
+ Key :: term().
keys({_, T}) ->
keys(T, []).
@@ -467,7 +519,9 @@ keys(nil, L) -> L.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--spec values(gb_tree()) -> [term()].
+-spec values(Tree) -> [Val] when
+ Tree :: gb_tree(),
+ Val :: term().
values({_, T}) ->
values(T, []).
@@ -478,7 +532,9 @@ values(nil, L) -> L.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--spec iterator(gb_tree()) -> [gb_tree_node()].
+-spec iterator(Tree) -> Iter when
+ Tree :: gb_tree(),
+ Iter :: iter().
iterator({_, T}) ->
iterator_1(T).
@@ -496,7 +552,11 @@ iterator({_, _, L, _} = T, As) ->
iterator(nil, As) ->
As.
--spec next([gb_tree_node()]) -> 'none' | {term(), term(), [gb_tree_node()]}.
+-spec next(Iter1) -> 'none' | {Key, Val, Iter2} when
+ Iter1 :: iter(),
+ Iter2 :: iter(),
+ Key :: term(),
+ Val :: term().
next([{X, V, _, T} | As]) ->
{X, V, iterator(T, As)};
@@ -505,7 +565,10 @@ next([]) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--spec map(fun((term(), term()) -> term()), gb_tree()) -> gb_tree().
+-spec map(Function, Tree1) -> Tree2 when
+ Function :: fun((K :: term(), V1 :: term()) -> V2 :: term()),
+ Tree1 :: gb_tree(),
+ Tree2 :: gb_tree().
map(F, {Size, Tree}) when is_function(F, 2) ->
{Size, map_1(F, Tree)}.
diff --git a/lib/stdlib/src/gen_event.erl b/lib/stdlib/src/gen_event.erl
index b00910771f..1c4a73680b 100644
--- a/lib/stdlib/src/gen_event.erl
+++ b/lib/stdlib/src/gen_event.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -44,6 +44,9 @@
system_code_change/4,
format_status/2]).
+-export_type([handler/0, handler_args/0, add_handler_ret/0,
+ del_handler_ret/0]).
+
-import(error_logger, [error_msg/2]).
-define(reply(X), From ! {element(2,Tag), X}).
@@ -113,7 +116,11 @@ behaviour_info(_Other) ->
%%---------------------------------------------------------------------------
--type handler() :: atom() | {atom(), term()}.
+-type handler() :: atom() | {atom(), term()}.
+-type handler_args() :: term().
+-type add_handler_ret() :: ok | term() | {'EXIT',term()}.
+-type del_handler_ret() :: ok | term() | {'EXIT',term()}.
+
-type emgr_name() :: {'local', atom()} | {'global', atom()}.
-type emgr_ref() :: atom() | {atom(), atom()} | {'global', atom()} | pid().
-type start_ret() :: {'ok', pid()} | {'error', term()}.
diff --git a/lib/stdlib/src/io.erl b/lib/stdlib/src/io.erl
index 6aeb076a0b..9f65bbfa3a 100644
--- a/lib/stdlib/src/io.erl
+++ b/lib/stdlib/src/io.erl
@@ -41,6 +41,7 @@
-type error_description() :: term(). % Whatever the io-server sends.
-type request_error() :: {'error',error_description()}.
+
%% XXX: Some uses of line() in this file may need to read erl_scan:location()
-type line() :: pos_integer().
@@ -66,12 +67,15 @@ o_request(Io, Request, Func) ->
end.
%% Put chars takes mixed *unicode* list from R13 onwards.
--spec put_chars(iodata()) -> 'ok'.
+-spec put_chars(CharData) -> 'ok' when
+ CharData :: unicode:chardata().
put_chars(Chars) ->
put_chars(default_output(), Chars).
--spec put_chars(device(), iodata()) -> 'ok'.
+-spec put_chars(IoDevice, IoData) -> 'ok' when
+ IoDevice :: device(),
+ IoData :: unicode:chardata().
put_chars(Io, Chars) ->
o_request(Io, {put_chars,unicode,Chars}, put_chars).
@@ -81,7 +85,8 @@ put_chars(Io, Chars) ->
nl() ->
nl(default_output()).
--spec nl(device()) -> 'ok'.
+-spec nl(IoDevice) -> 'ok' when
+ IoDevice :: device().
nl(Io) ->
% o_request(Io, {put_chars,io_lib:nl()}).
@@ -92,7 +97,8 @@ nl(Io) ->
columns() ->
columns(default_output()).
--spec columns(device()) -> {'ok', pos_integer()} | {'error', 'enotsup'}.
+-spec columns(IoDevice) -> {'ok', pos_integer()} | {'error', 'enotsup'} when
+ IoDevice :: device().
columns(Io) ->
case request(Io, {get_geometry,columns}) of
@@ -107,7 +113,8 @@ columns(Io) ->
rows() ->
rows(default_output()).
--spec rows(device()) -> {'ok', pos_integer()} | {'error', 'enotsup'}.
+-spec rows(IoDevice) -> {'ok', pos_integer()} | {'error', 'enotsup'} when
+ IoDevice :: device().
rows(Io) ->
case request(Io,{get_geometry,rows}) of
@@ -117,22 +124,36 @@ rows(Io) ->
{error,enotsup}
end.
--spec get_chars(prompt(), non_neg_integer()) -> iodata() | 'eof'.
+-spec get_chars(Prompt, Count) -> Data | 'eof' when
+ Prompt :: prompt(),
+ Count :: non_neg_integer(),
+ Data :: [unicode:unicode_char()] | unicode:unicode_binary().
get_chars(Prompt, N) ->
get_chars(default_input(), Prompt, N).
--spec get_chars(device(), prompt(), non_neg_integer()) -> iodata() | 'eof'.
+-spec get_chars(IoDevice, Prompt, Count) -> Data | 'eof' | {error, Reason} when
+ IoDevice :: device(),
+ Prompt :: prompt(),
+ Count :: non_neg_integer(),
+ Reason :: term(),
+ Data :: [unicode:unicode_char()] | unicode:unicode_binary().
get_chars(Io, Prompt, N) when is_integer(N), N >= 0 ->
request(Io, {get_chars,unicode,Prompt,N}).
--spec get_line(prompt()) -> iodata() | 'eof' | {'error', term()}.
+-spec get_line(Prompt) -> Data | 'eof' | {'error', Reason} when
+ Prompt :: prompt(),
+ Reason :: term(),
+ Data :: [unicode:unicode_char()] | unicode:unicode_binary().
get_line(Prompt) ->
get_line(default_input(), Prompt).
--spec get_line(device(), prompt()) -> iodata() | 'eof' | {'error', term()}.
+-spec get_line(IoDevice, Prompt) -> Data | 'eof' | {'error', term()} when
+ IoDevice :: device(),
+ Prompt :: prompt(),
+ Data :: [unicode:unicode_char()] | unicode:unicode_binary().
get_line(Io, Prompt) ->
request(Io, {get_line,unicode,Prompt}).
@@ -156,46 +177,62 @@ get_password(Io) ->
getopts() ->
getopts(default_input()).
--spec getopts(device()) -> [opt_pair()].
+-spec getopts(IoDevice) -> [opt_pair()] when
+ IoDevice :: device().
getopts(Io) ->
request(Io, getopts).
-type setopt() :: 'binary' | 'list' | opt_pair().
--spec setopts([setopt()]) -> 'ok' | {'error', term()}.
+-spec setopts(Opts) -> 'ok' | {'error', Reason} when
+ Opts :: [setopt()],
+ Reason :: term().
setopts(Opts) ->
setopts(default_input(), Opts).
--spec setopts(device(), [setopt()]) -> 'ok' | {'error', term()}.
+-spec setopts(IoDevice, Opts) -> 'ok' | {'error', Reason} when
+ IoDevice :: device(),
+ Opts :: [setopt()],
+ Reason :: term().
setopts(Io, Opts) ->
request(Io, {setopts, Opts}).
%% Writing and reading Erlang terms.
--spec write(term()) -> 'ok'.
+-spec write(Term) -> 'ok' when
+ Term :: term().
write(Term) ->
write(default_output(), Term).
--spec write(device(), term()) -> 'ok'.
+-spec write(IoDevice, Term) -> 'ok' when
+ IoDevice :: device(),
+ Term :: term().
write(Io, Term) ->
o_request(Io, {write,Term}, write).
--spec read(prompt()) ->
- {'ok', term()} | 'eof' | {'error', erl_scan:error_info()}.
+-spec read(Prompt) -> Result when
+ Prompt :: prompt(),
+ Result :: {'ok', Term :: term()}
+ | 'eof'
+ | {'error', ErrorInfo :: erl_scan:error_info()}.
% Read does not use get_until as erl_scan does not work with unicode
% XXX:PaN fixme?
read(Prompt) ->
read(default_input(), Prompt).
--spec read(device(), prompt()) ->
- {'ok', term()} | 'eof' | {'error', erl_scan:error_info()}.
+-spec read(IoDevice, Prompt) -> Result when
+ IoDevice :: device(),
+ Prompt :: prompt(),
+ Result :: {'ok', Term :: term()}
+ | 'eof'
+ | {'error', ErrorInfo :: erl_scan:error_info()}.
read(Io, Prompt) ->
case request(Io, {get_until,unicode,Prompt,erl_scan,tokens,[1]}) of
@@ -211,9 +248,13 @@ read(Io, Prompt) ->
Other
end.
--spec read(device(), prompt(), line()) ->
- {'ok', term(), line()} | {'eof', line()} |
- {'error', erl_scan:error_info(), line()}.
+-spec read(IoDevice, Prompt, StartLine) -> Result when
+ IoDevice :: device(),
+ Prompt :: prompt(),
+ StartLine :: line(),
+ Result :: {'ok', Term :: term(), EndLine :: line()}
+ | {'eof', EndLine :: line()}
+ | {'error', ErrorInfo :: erl_scan:error_info(), ErrorLine :: line()}.
read(Io, Prompt, StartLine) when is_integer(StartLine) ->
case request(Io, {get_until,unicode,Prompt,erl_scan,tokens,[StartLine]}) of
@@ -239,28 +280,40 @@ conv_reason(_, _Reason) -> badarg.
-type format() :: atom() | string() | binary().
--spec fwrite(format()) -> 'ok'.
+-spec fwrite(Format) -> 'ok' when
+ Format :: format().
fwrite(Format) ->
format(Format).
--spec fwrite(format(), [term()]) -> 'ok'.
+-spec fwrite(Format, Data) -> 'ok' when
+ Format :: format(),
+ Data :: [term()].
fwrite(Format, Args) ->
format(Format, Args).
--spec fwrite(device(), format(), [term()]) -> 'ok'.
+-spec fwrite(IoDevice, Format, Data) -> 'ok' when
+ IoDevice :: device(),
+ Format :: format(),
+ Data :: [term()].
fwrite(Io, Format, Args) ->
format(Io, Format, Args).
--spec fread(prompt(), format()) -> {'ok', [term()]} | 'eof' | {'error',term()}.
+-spec fread(Prompt, Format) -> Result when
+ Prompt :: prompt(),
+ Format :: format(),
+ Result :: {'ok', Terms :: [term()]} | 'eof' | {'error', What :: term()}.
fread(Prompt, Format) ->
fread(default_input(), Prompt, Format).
--spec fread(device(), prompt(), format()) ->
- {'ok', [term()]} | 'eof' | {'error',term()}.
+-spec fread(IoDevice, Prompt, Format) -> Result when
+ IoDevice :: device(),
+ Prompt :: prompt(),
+ Format :: format(),
+ Result :: {'ok', Terms :: [term()]} | 'eof' | {'error', What :: term()}.
fread(Io, Prompt, Format) ->
case request(Io, {fread,Prompt,Format}) of
@@ -270,73 +323,104 @@ fread(Io, Prompt, Format) ->
Other
end.
--spec format(format()) -> 'ok'.
+-spec format(Format) -> 'ok' when
+ Format :: format().
format(Format) ->
format(Format, []).
--spec format(format(), [term()]) -> 'ok'.
+-spec format(Format, Data) -> 'ok' when
+ Format :: format(),
+ Data :: [term()].
format(Format, Args) ->
format(default_output(), Format, Args).
--spec format(device(), format(), [term()]) -> 'ok'.
+-spec format(IoDevice, Format, Data) -> 'ok' when
+ IoDevice :: device(),
+ Format :: format(),
+ Data :: [term()].
format(Io, Format, Args) ->
o_request(Io, {format,Format,Args}, format).
%% Scanning Erlang code.
--spec scan_erl_exprs(prompt()) -> erl_scan:tokens_result() | request_error().
+-spec scan_erl_exprs(Prompt) -> Result when
+ Prompt :: prompt(),
+ Result :: erl_scan:tokens_result() | request_error().
scan_erl_exprs(Prompt) ->
scan_erl_exprs(default_input(), Prompt, 1).
--spec scan_erl_exprs(device(), prompt()) -> erl_scan:tokens_result() | request_error().
+-spec scan_erl_exprs(Device, Prompt) -> Result when
+ Device :: device(),
+ Prompt :: prompt(),
+ Result :: erl_scan:tokens_result() | request_error().
scan_erl_exprs(Io, Prompt) ->
scan_erl_exprs(Io, Prompt, 1).
--spec scan_erl_exprs(device(), prompt(), line()) -> erl_scan:tokens_result() | request_error().
+-spec scan_erl_exprs(Device, Prompt, StartLine) -> Result when
+ Device :: device(),
+ Prompt :: prompt(),
+ StartLine :: line(),
+ Result :: erl_scan:tokens_result() | request_error().
scan_erl_exprs(Io, Prompt, Pos0) ->
request(Io, {get_until,unicode,Prompt,erl_scan,tokens,[Pos0]}).
--spec scan_erl_form(prompt()) -> erl_scan:tokens_result() | request_error().
+-spec scan_erl_form(Prompt) -> Result when
+ Prompt :: prompt(),
+ Result :: erl_scan:tokens_result() | request_error().
scan_erl_form(Prompt) ->
scan_erl_form(default_input(), Prompt, 1).
--spec scan_erl_form(device(), prompt()) -> erl_scan:tokens_result() | request_error().
+-spec scan_erl_form(IoDevice, Prompt) -> Result when
+ IoDevice :: device(),
+ Prompt :: prompt(),
+ Result :: erl_scan:tokens_result() | request_error().
scan_erl_form(Io, Prompt) ->
scan_erl_form(Io, Prompt, 1).
--spec scan_erl_form(device(), prompt(), line()) -> erl_scan:tokens_result() | request_error().
+-spec scan_erl_form(IoDevice, Prompt, StartLine) -> Result when
+ IoDevice :: device(),
+ Prompt :: prompt(),
+ StartLine :: line(),
+ Result :: erl_scan:tokens_result() | request_error().
scan_erl_form(Io, Prompt, Pos0) ->
request(Io, {get_until,unicode,Prompt,erl_scan,tokens,[Pos0]}).
%% Parsing Erlang code.
--type erl_parse_expr_list() :: [_]. %% XXX: should be imported from erl_parse
-
--type parse_ret() :: {'ok', erl_parse_expr_list(), line()}
- | {'eof', line()}
- | {'error', erl_scan:error_info(), line()}
+-type parse_ret() :: {'ok', ExprList :: erl_parse:abstract_expr(), EndLine :: line()}
+ | {'eof', EndLine :: line()}
+ | {'error', ErrorInfo :: erl_scan:error_info(), ErrorLine :: line()}
| request_error().
--spec parse_erl_exprs(prompt()) -> parse_ret().
+-spec parse_erl_exprs(Prompt) -> Result when
+ Prompt :: prompt(),
+ Result :: parse_ret().
parse_erl_exprs(Prompt) ->
parse_erl_exprs(default_input(), Prompt, 1).
--spec parse_erl_exprs(device(), prompt()) -> parse_ret().
+-spec parse_erl_exprs(IoDevice, Prompt) -> Result when
+ IoDevice :: device(),
+ Prompt :: prompt(),
+ Result :: parse_ret().
parse_erl_exprs(Io, Prompt) ->
parse_erl_exprs(Io, Prompt, 1).
--spec parse_erl_exprs(device(), prompt(), line()) -> parse_ret().
+-spec parse_erl_exprs(IoDevice, Prompt, StartLine) -> Result when
+ IoDevice :: device(),
+ Prompt :: prompt(),
+ StartLine :: line(),
+ Result :: parse_ret().
parse_erl_exprs(Io, Prompt, Pos0) ->
case request(Io, {get_until,unicode,Prompt,erl_scan,tokens,[Pos0]}) of
@@ -349,24 +433,31 @@ parse_erl_exprs(Io, Prompt, Pos0) ->
Other
end.
--type erl_parse_absform() :: _. %% XXX: should be imported from erl_parse
-
--type parse_form_ret() :: {'ok', erl_parse_absform(), line()}
- | {'eof', line()}
- | {'error', erl_scan:error_info(), line()}
+-type parse_form_ret() :: {'ok', AbsForm :: erl_parse:abstract_form(), EndLine :: line()}
+ | {'eof', EndLine :: line()}
+ | {'error', ErrorInfo :: erl_scan:error_info(), ErrorLine :: line()}
| request_error().
--spec parse_erl_form(prompt()) -> parse_form_ret().
+-spec parse_erl_form(Prompt) -> Result when
+ Prompt :: prompt(),
+ Result :: parse_form_ret().
parse_erl_form(Prompt) ->
parse_erl_form(default_input(), Prompt, 1).
--spec parse_erl_form(device(), prompt()) -> parse_form_ret().
+-spec parse_erl_form(IoDevice, Prompt) -> Result when
+ IoDevice :: device(),
+ Prompt :: prompt(),
+ Result :: parse_form_ret().
parse_erl_form(Io, Prompt) ->
parse_erl_form(Io, Prompt, 1).
--spec parse_erl_form(device(), prompt(), line()) -> parse_form_ret().
+-spec parse_erl_form(IoDevice, Prompt, StartLine) -> Result when
+ IoDevice :: device(),
+ Prompt :: prompt(),
+ StartLine :: line(),
+ Result :: parse_form_ret().
parse_erl_form(Io, Prompt, Pos0) ->
case request(Io, {get_until,unicode,Prompt,erl_scan,tokens,[Pos0]}) of
diff --git a/lib/stdlib/src/io_lib.erl b/lib/stdlib/src/io_lib.erl
index 4ca9d079b7..54c7283abf 100644
--- a/lib/stdlib/src/io_lib.erl
+++ b/lib/stdlib/src/io_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -75,35 +75,57 @@
collect_line/2, collect_line/3, collect_line/4,
get_until/3, get_until/4]).
--export_type([chars/0]).
+-export_type([chars/0, continuation/0]).
%%----------------------------------------------------------------------
- %% XXX: overapproximates a deep list of (unicode) characters
--type chars() :: [_].
+-type chars() :: [char() | chars()].
-type depth() :: -1 | non_neg_integer().
+-opaque continuation() :: {_, _, _, _}. % XXX: refine
+
%%----------------------------------------------------------------------
%% Interface calls to sub-modules.
--spec fwrite(io:format(), [term()]) -> chars().
+-spec fwrite(Format, Data) -> chars() | UnicodeList when
+ Format :: io:format(),
+ Data :: [term()],
+ UnicodeList :: [unicode:unicode_char()],
+ Data :: [term()].
fwrite(Format, Args) ->
format(Format, Args).
--spec fread(string(), string()) -> io_lib_fread:fread_2_ret().
+-spec fread(Format, String) -> Result when
+ Format :: string(),
+ String :: string(),
+ Result :: {'ok', InputList :: chars(), LeftOverChars :: string()}
+ | {'more', RestFormat :: string(),
+ Nchars :: non_neg_integer(),
+ InputStack :: chars()}
+ | {'error', What :: term()}.
fread(Chars, Format) ->
io_lib_fread:fread(Chars, Format).
--spec fread(io_lib_fread:continuation(), string(), string()) ->
- io_lib_fread:fread_3_ret().
+-spec fread(Continuation, String, Format) -> Return when
+ Continuation :: continuation() | [],
+ String :: string(),
+ Format :: string(),
+ Return :: {'more', Continuation1 :: continuation()}
+ | {'done', Result, LeftOverChars :: string()},
+ Result :: {'ok', InputList :: chars()}
+ | 'eof'
+ | {'error', What :: term()}.
fread(Cont, Chars, Format) ->
io_lib_fread:fread(Cont, Chars, Format).
--spec format(io:format(), [term()]) -> chars().
+-spec format(Format, Data) -> chars() | UnicodeList when
+ Format :: io:format(),
+ Data :: [term()],
+ UnicodeList :: [unicode:unicode_char()].
format(Format, Args) ->
case catch io_lib_format:fwrite(Format, Args) of
@@ -113,17 +135,24 @@ format(Format, Args) ->
Other
end.
--spec print(term()) -> chars().
+-spec print(Term) -> chars() when
+ Term :: term().
print(Term) ->
io_lib_pretty:print(Term).
--spec print(term(), non_neg_integer(), non_neg_integer(), depth()) -> chars().
+-spec print(Term, Column, LineLength, Depth) -> chars() when
+ Term :: term(),
+ Column :: non_neg_integer(),
+ LineLength :: non_neg_integer(),
+ Depth :: depth().
print(Term, Column, LineLength, Depth) ->
io_lib_pretty:print(Term, Column, LineLength, Depth).
--spec indentation(string(), integer()) -> integer().
+-spec indentation(String, StartIndent) -> integer() when
+ String :: string(),
+ StartIndent :: integer().
indentation(Chars, Current) ->
io_lib_format:indentation(Chars, Current).
@@ -158,7 +187,8 @@ format_prompt(Format, Args) ->
%% Return a (non-flattened) list of characters giving a printed
%% representation of the term. write/3 is for backward compatibility.
--spec write(term()) -> chars().
+-spec write(Term) -> chars() when
+ Term :: term().
write(Term) -> write(Term, -1).
@@ -169,7 +199,9 @@ write(Term, D, true) ->
write(Term, D, false) ->
write(Term, D).
--spec write(term(), depth()) -> chars().
+-spec write(Term, Depth) -> chars() when
+ Term :: term(),
+ Depth :: depth().
write(_Term, 0) -> "...";
write(Term, _D) when is_integer(Term) -> integer_to_list(Term);
@@ -234,7 +266,8 @@ write_binary_body(B, _D) ->
%% write_atom(Atom) -> [Char]
%% Generate the list of characters needed to print an atom.
--spec write_atom(atom()) -> chars().
+-spec write_atom(Atom) -> chars() when
+ Atom :: atom().
write_atom(Atom) ->
Chars = atom_to_list(Atom),
@@ -283,7 +316,8 @@ name_char(_) -> false.
%% write_string([Char]) -> [Char]
%% Generate the list of characters needed to print a string.
--spec write_string(string()) -> chars().
+-spec write_string(String) -> chars() when
+ String :: string().
write_string(S) ->
write_string(S, $"). %"
@@ -330,7 +364,8 @@ string_char(_,C, _, Tail) when C < $\240-> %Other control characters.
%% Generate the list of characters needed to print a character constant.
%% Must special case SPACE, $\s, here.
--spec write_char(char()) -> chars().
+-spec write_char(Char) -> chars() when
+ Char :: char().
write_char($\s) -> "$\\s"; %Must special case this.
write_char(C) when is_integer(C), C >= $\000, C =< $\377 ->
@@ -346,7 +381,8 @@ write_unicode_char(Uni) ->
%% Return true if CharList is a (possibly deep) list of characters, else
%% false.
--spec char_list(term()) -> boolean().
+-spec char_list(Term) -> boolean() when
+ Term :: term().
char_list([C|Cs]) when is_integer(C), C >= $\000, C =< $\377 ->
char_list(Cs);
@@ -362,7 +398,8 @@ unicode_char_list([C|Cs]) when is_integer(C), C >= 0, C < 16#D800;
unicode_char_list([]) -> true;
unicode_char_list(_) -> false. %Everything else is false
--spec deep_char_list(term()) -> boolean().
+-spec deep_char_list(Term) -> boolean() when
+ Term :: term().
deep_char_list(Cs) ->
deep_char_list(Cs, []).
@@ -399,7 +436,8 @@ deep_unicode_char_list(_, _More) -> %Everything else is false
%% Return true if CharList is a list of printable characters, else
%% false.
--spec printable_list(term()) -> boolean().
+-spec printable_list(Term) -> boolean() when
+ Term :: term().
printable_list([C|Cs]) when is_integer(C), C >= $\040, C =< $\176 ->
printable_list(Cs);
diff --git a/lib/stdlib/src/io_lib_fread.erl b/lib/stdlib/src/io_lib_fread.erl
index 33553692bc..52aa4d073c 100644
--- a/lib/stdlib/src/io_lib_fread.erl
+++ b/lib/stdlib/src/io_lib_fread.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -22,36 +22,24 @@
-export([fread/2,fread/3]).
--export_type([continuation/0, fread_2_ret/0, fread_3_ret/0]).
-
-import(lists, [reverse/1,reverse/2]).
%%-----------------------------------------------------------------------
-%% Local types
-%%-----------------------------------------------------------------------
-
--type done_arg2() :: {'ok', io_lib:chars()} | 'eof' | {'error', term()}.
-
-%%-----------------------------------------------------------------------
-%% Types also used in other files
-%%-----------------------------------------------------------------------
-
--type continuation() :: [] | {_, _, _, _}. % XXX: refine
-
--type fread_2_ret() :: {'ok', io_lib:chars(), string()}
- | {'more', string(), non_neg_integer(), io_lib:chars()}
- | {'error', term()}.
--type fread_3_ret() :: {'more', continuation()}
- | {'done', done_arg2(), string()}.
-
-%%-----------------------------------------------------------------------
%% fread(Continuation, CharList, FormatString)
%% This is the main function into the re-entrant formatted reader. It
%% repeatedly collects lines and calls fread/2 to format the input until
%% all the format string has been used. And it counts the characters.
--spec fread(io_lib_fread:continuation(), string(), string()) -> fread_3_ret().
+-spec fread(Continuation, String, Format) -> Return when
+ Continuation :: io_lib:continuation() | [],
+ String :: string(),
+ Format :: string(),
+ Return :: {'more', Continuation1 :: io_lib:continuation()}
+ | {'done', Result, LeftOverChars :: string()},
+ Result :: {'ok', InputList :: io_lib:chars()}
+ | 'eof'
+ | {'error', What :: term()}.
fread([], Chars, Format) ->
%%io:format("FREAD: ~w `~s'~n", [Format,Chars]),
@@ -106,7 +94,14 @@ fread_line(Format0, Line, N0, Results0, More, Newline) ->
%% WHITE Skip white space
%% X Literal X
--spec fread(string(), string()) -> fread_2_ret().
+-spec fread(Format, String) -> Result when
+ Format :: string(),
+ String :: string(),
+ Result :: {'ok', InputList :: io_lib:chars(), LeftOverChars :: string()}
+ | {'more', RestFormat :: string(),
+ Nchars :: non_neg_integer(),
+ InputStack :: io_lib:chars()}
+ | {'error', What :: term()}.
fread(Format, Line) ->
fread(Format, Line, 0, []).
diff --git a/lib/stdlib/src/lib.erl b/lib/stdlib/src/lib.erl
index b2cfb00de9..c303ae60b5 100644
--- a/lib/stdlib/src/lib.erl
+++ b/lib/stdlib/src/lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -38,7 +38,9 @@ flush_receive() ->
%%
%% Functions for doing standard system format i/o.
%%
--spec error_message(atom() | string() | binary(), [term()]) -> 'ok'.
+-spec error_message(Format, Args) -> 'ok' when
+ Format :: io:format(),
+ Args :: [term()].
error_message(Format, Args) ->
io:format(<<"** ~s **\n">>, [io_lib:format(Format, Args)]).
@@ -55,17 +57,23 @@ progname() ->
no_prog_name
end.
--spec nonl(string()) -> string().
+-spec nonl(String1) -> String2 when
+ String1 :: string(),
+ String2 :: string().
nonl([10]) -> [];
nonl([]) -> [];
nonl([H|T]) -> [H|nonl(T)].
--spec send(pid() | atom() | {atom(), node()}, term()) -> term().
+-spec send(To, Msg) -> Msg when
+ To :: pid() | atom() | {atom(), node()},
+ Msg :: term().
send(To, Msg) -> To ! Msg.
--spec sendw(pid() | atom() | {atom(), node()}, term()) -> term().
+-spec sendw(To, Msg) -> Msg when
+ To :: pid() | atom() | {atom(), node()},
+ Msg :: term().
sendw(To, Msg) ->
To ! {self(), Msg},
@@ -89,7 +97,7 @@ eval_str(Str) when is_list(Str) ->
true ->
case erl_parse:parse_exprs(Toks) of
{ok, Exprs} ->
- case catch erl_eval:exprs(Exprs, []) of
+ case catch erl_eval:exprs(Exprs, erl_eval:new_bindings()) of
{value, Val, _} ->
{ok, Val};
Other ->
diff --git a/lib/stdlib/src/lists.erl b/lib/stdlib/src/lists.erl
index c669c1f7c1..bba46e4cb6 100644
--- a/lib/stdlib/src/lists.erl
+++ b/lib/stdlib/src/lists.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -54,13 +54,21 @@
%% append(X, Y) appends lists X and Y
--spec append([T], [T]) -> [T].
+-spec append(List1, List2) -> List3 when
+ List1 :: [T],
+ List2 :: [T],
+ List3 :: [T],
+ T :: term().
append(L1, L2) -> L1 ++ L2.
%% append(L) appends the list of lists L
--spec append([[T]]) -> [T].
+-spec append(ListOfLists) -> List1 when
+ ListOfLists :: [List],
+ List :: [T],
+ List1 :: [T],
+ T :: term().
append([E]) -> E;
append([H|T]) -> H ++ append(T);
@@ -68,13 +76,20 @@ append([]) -> [].
%% subtract(List1, List2) subtract elements in List2 form List1.
--spec subtract([T], [T]) -> [T].
+-spec subtract(List1, List2) -> List3 when
+ List1 :: [T],
+ List2 :: [T],
+ List3 :: [T],
+ T :: term().
subtract(L1, L2) -> L1 -- L2.
%% reverse(L) reverse all elements in the list L. Is now a BIF!
--spec reverse([T]) -> [T].
+-spec reverse(List1) -> List2 when
+ List1 :: [T],
+ List2 :: [T],
+ T :: term().
reverse([] = L) ->
L;
@@ -93,13 +108,21 @@ reverse([A, B | L]) ->
%% nth(N, L) returns the N`th element of the list L
%% nthtail(N, L) returns the N`th tail of the list L
--spec nth(pos_integer(), [T,...]) -> T.
+-spec nth(N, List) -> Elem when
+ N :: pos_integer(),
+ List :: [T,...],
+ Elem :: T,
+ T :: term().
nth(1, [H|_]) -> H;
nth(N, [_|T]) when N > 1 ->
nth(N - 1, T).
--spec nthtail(non_neg_integer(), [T,...]) -> [T].
+-spec nthtail(N, List) -> Tail when
+ N :: non_neg_integer(),
+ List :: [T,...],
+ Tail :: [T],
+ T :: term().
nthtail(1, [_|T]) -> T;
nthtail(N, [_|T]) when N > 1 ->
@@ -108,7 +131,10 @@ nthtail(0, L) when is_list(L) -> L.
%% prefix(Prefix, List) -> (true | false)
--spec prefix([T], [T]) -> boolean().
+-spec prefix(List1, List2) -> boolean() when
+ List1 :: [T],
+ List2 :: [T],
+ T :: term().
prefix([X|PreTail], [X|Tail]) ->
prefix(PreTail, Tail);
@@ -117,7 +143,10 @@ prefix([_|_], List) when is_list(List) -> false.
%% suffix(Suffix, List) -> (true | false)
--spec suffix([T], [T]) -> boolean().
+-spec suffix(List1, List2) -> boolean() when
+ List1 :: [T],
+ List2 :: [T],
+ T :: term().
suffix(Suffix, List) ->
Delta = length(List) - length(Suffix),
@@ -125,7 +154,10 @@ suffix(Suffix, List) ->
%% last(List) returns the last element in a list.
--spec last([T,...]) -> T.
+-spec last(List) -> Last when
+ List :: [T,...],
+ Last :: T,
+ T :: term().
last([E|Es]) -> last(E, Es).
@@ -137,7 +169,10 @@ last(E, []) -> E.
%% returns the sequence Min..Max
%% Min <= Max and Min and Max must be integers
--spec seq(integer(), integer()) -> [integer()].
+-spec seq(From, To) -> Seq when
+ From :: integer(),
+ To :: integer(),
+ Seq :: [integer()].
seq(First, Last)
when is_integer(First), is_integer(Last), First-1 =< Last ->
@@ -152,7 +187,11 @@ seq_loop(1, X, L) ->
seq_loop(0, _, L) ->
L.
--spec seq(integer(), integer(), integer()) -> [integer()].
+-spec seq(From, To, Incr) -> Seq when
+ From :: integer(),
+ To :: integer(),
+ Incr :: integer(),
+ Seq :: [integer()].
seq(First, Last, Inc)
when is_integer(First), is_integer(Last), is_integer(Inc) ->
@@ -178,7 +217,8 @@ seq_loop(0, _, _, L) ->
%% sum(L) returns the sum of the elements in L
--spec sum([number()]) -> number().
+-spec sum(List) -> number() when
+ List :: [number()].
sum(L) -> sum(L, 0).
@@ -188,7 +228,11 @@ sum([], Sum) -> Sum.
%% duplicate(N, X) -> [X,X,X,.....,X] (N times)
%% return N copies of X
--spec duplicate(non_neg_integer(), T) -> [T].
+-spec duplicate(N, Elem) -> List when
+ N :: non_neg_integer(),
+ Elem :: T,
+ List :: [T],
+ T :: term().
duplicate(N, X) when is_integer(N), N >= 0 -> duplicate(N, X, []).
@@ -197,7 +241,10 @@ duplicate(N, X, L) -> duplicate(N-1, X, [X|L]).
%% min(L) -> returns the minimum element of the list L
--spec min([T,...]) -> T.
+-spec min(List) -> Min when
+ List :: [T,...],
+ Min :: T,
+ T :: term().
min([H|T]) -> min(T, H).
@@ -207,7 +254,10 @@ min([], Min) -> Min.
%% max(L) -> returns the maximum element of the list L
--spec max([T,...]) -> T.
+-spec max(List) -> Max when
+ List :: [T,...],
+ Max :: T,
+ T :: term().
max([H|T]) -> max(T, H).
@@ -218,12 +268,21 @@ max([], Max) -> Max.
%% sublist(List, Start, Length)
%% Returns the sub-list starting at Start of length Length.
--spec sublist([T], pos_integer(), non_neg_integer()) -> [T].
+-spec sublist(List1, Start, Len) -> List2 when
+ List1 :: [T],
+ List2 :: [T],
+ Start :: pos_integer(),
+ Len :: non_neg_integer(),
+ T :: term().
sublist(List, S, L) when is_integer(L), L >= 0 ->
sublist(nthtail(S-1, List), L).
--spec sublist([T], non_neg_integer()) -> [T].
+-spec sublist(List1, Len) -> List2 when
+ List1 :: [T],
+ List2 :: [T],
+ Len :: non_neg_integer(),
+ T :: term().
sublist(List, L) when is_integer(L), is_list(List) ->
sublist_2(List, L).
@@ -238,7 +297,11 @@ sublist_2(List, L) when is_list(List), L > 0 ->
%% delete(Item, List) -> List'
%% Delete the first occurrence of Item from the list L.
--spec delete(T, [T]) -> [T].
+-spec delete(Elem, List1) -> List2 when
+ Elem :: T,
+ List1 :: [T],
+ List2 :: [T],
+ T :: term().
delete(Item, [Item|Rest]) -> Rest;
delete(Item, [H|Rest]) ->
@@ -248,7 +311,12 @@ delete(_, []) -> [].
%% Return [{X0, Y0}, {X1, Y1}, ..., {Xn, Yn}] for lists [X0, X1, ...,
%% Xn] and [Y0, Y1, ..., Yn].
--spec zip([A], [B]) -> [{A, B}].
+-spec zip(List1, List2) -> List3 when
+ List1 :: [A],
+ List2 :: [B],
+ List3 :: [{A, B}],
+ A :: term(),
+ B :: term().
zip([X | Xs], [Y | Ys]) -> [{X, Y} | zip(Xs, Ys)];
zip([], []) -> [].
@@ -256,7 +324,12 @@ zip([], []) -> [].
%% Return {[X0, X1, ..., Xn], [Y0, Y1, ..., Yn]}, for a list [{X0, Y0},
%% {X1, Y1}, ..., {Xn, Yn}].
--spec unzip([{A, B}]) -> {[A], [B]}.
+-spec unzip(List1) -> {List2, List3} when
+ List1 :: [{A, B}],
+ List2 :: [A],
+ List3 :: [B],
+ A :: term(),
+ B :: term().
unzip(Ts) -> unzip(Ts, [], []).
@@ -266,7 +339,14 @@ unzip([], Xs, Ys) -> {reverse(Xs), reverse(Ys)}.
%% Return [{X0, Y0, Z0}, {X1, Y1, Z1}, ..., {Xn, Yn, Zn}] for lists [X0,
%% X1, ..., Xn], [Y0, Y1, ..., Yn] and [Z0, Z1, ..., Zn].
--spec zip3([A], [B], [C]) -> [{A, B, C}].
+-spec zip3(List1, List2, List3) -> List4 when
+ List1 :: [A],
+ List2 :: [B],
+ List3 :: [C],
+ List4 :: [{A, B, C}],
+ A :: term(),
+ B :: term(),
+ C :: term().
zip3([X | Xs], [Y | Ys], [Z | Zs]) -> [{X, Y, Z} | zip3(Xs, Ys, Zs)];
zip3([], [], []) -> [].
@@ -274,7 +354,14 @@ zip3([], [], []) -> [].
%% Return {[X0, X1, ..., Xn], [Y0, Y1, ..., Yn], [Z0, Z1, ..., Zn]}, for
%% a list [{X0, Y0, Z0}, {X1, Y1, Z1}, ..., {Xn, Yn, Zn}].
--spec unzip3([{A, B, C}]) -> {[A], [B], [C]}.
+-spec unzip3(List1) -> {List2, List3, List4} when
+ List1 :: [{A, B, C}],
+ List2 :: [A],
+ List3 :: [B],
+ List4 :: [C],
+ A :: term(),
+ B :: term(),
+ C :: term().
unzip3(Ts) -> unzip3(Ts, [], [], []).
@@ -286,7 +373,14 @@ unzip3([], Xs, Ys, Zs) ->
%% Return [F(X0, Y0), F(X1, Y1), ..., F(Xn, Yn)] for lists [X0, X1, ...,
%% Xn] and [Y0, Y1, ..., Yn].
--spec zipwith(fun((X, Y) -> R), [X], [Y]) -> [R].
+-spec zipwith(Combine, List1, List2) -> List3 when
+ Combine :: fun((X, Y) -> T),
+ List1 :: [X],
+ List2 :: [Y],
+ List3 :: [T],
+ X :: term(),
+ Y :: term(),
+ T :: term().
zipwith(F, [X | Xs], [Y | Ys]) -> [F(X, Y) | zipwith(F, Xs, Ys)];
zipwith(F, [], []) when is_function(F, 2) -> [].
@@ -294,7 +388,16 @@ zipwith(F, [], []) when is_function(F, 2) -> [].
%% Return [F(X0, Y0, Z0), F(X1, Y1, Z1), ..., F(Xn, Yn, Zn)] for lists
%% [X0, X1, ..., Xn], [Y0, Y1, ..., Yn] and [Z0, Z1, ..., Zn].
--spec zipwith3(fun((X, Y, Z) -> R), [X], [Y], [Z]) -> [R].
+-spec zipwith3(Combine, List1, List2, List3) -> List4 when
+ Combine :: fun((X, Y, Z) -> T),
+ List1 :: [X],
+ List2 :: [Y],
+ List3 :: [Z],
+ List4 :: [T],
+ X :: term(),
+ Y :: term(),
+ Z :: term(),
+ T :: term().
zipwith3(F, [X | Xs], [Y | Ys], [Z | Zs]) ->
[F(X, Y, Z) | zipwith3(F, Xs, Ys, Zs)];
@@ -303,7 +406,10 @@ zipwith3(F, [], [], []) when is_function(F, 3) -> [].
%% sort(List) -> L
%% sorts the list L
--spec sort([T]) -> [T].
+-spec sort(List1) -> List2 when
+ List1 :: [T],
+ List2 :: [T],
+ T :: term().
sort([X, Y | L] = L0) when X =< Y ->
case L of
@@ -350,7 +456,11 @@ sort_1(X, [], R) ->
%% merge(List) -> L
%% merges a list of sorted lists
--spec merge([[T]]) -> [T].
+-spec merge(ListOfLists) -> List1 when
+ ListOfLists :: [List],
+ List :: [T],
+ List1 :: [T],
+ T :: term().
merge(L) ->
mergel(L, []).
@@ -358,7 +468,14 @@ merge(L) ->
%% merge3(X, Y, Z) -> L
%% merges three sorted lists X, Y and Z
--spec merge3([X], [Y], [Z]) -> [(X | Y | Z)].
+-spec merge3(List1, List2, List3) -> List4 when
+ List1 :: [X],
+ List2 :: [Y],
+ List3 :: [Z],
+ List4 :: [(X | Y | Z)],
+ X :: term(),
+ Y :: term(),
+ Z :: term().
merge3(L1, [], L3) ->
merge(L1, L3);
@@ -382,7 +499,12 @@ rmerge3(L1, [H2 | T2], [H3 | T3]) ->
%% merge(X, Y) -> L
%% merges two sorted lists X and Y
--spec merge([X], [Y]) -> [(X | Y)].
+-spec merge(List1, List2) -> List3 when
+ List1 :: [X],
+ List2 :: [Y],
+ List3 :: [(X | Y)],
+ X :: term(),
+ Y :: term().
merge(T1, []) ->
T1;
@@ -405,8 +527,9 @@ rmerge(T1, [H2 | T2]) ->
%% in L - the elements in L can be atoms, numbers of strings.
%% Returns a list of characters.
--type concat_thing() :: atom() | integer() | float() | string().
--spec concat([concat_thing()]) -> string().
+-spec concat(Things) -> string() when
+ Things :: [Thing],
+ Thing :: atom() | integer() | float() | string().
concat(List) ->
flatmap(fun thing_to_list/1, List).
@@ -420,12 +543,17 @@ thing_to_list(X) when is_list(X) -> X. %Assumed to be a string
%% flatten(List, Tail)
%% Flatten a list, adding optional tail.
--spec flatten([term()]) -> [term()].
+-spec flatten(DeepList) -> List when
+ DeepList :: [term() | DeepList],
+ List :: [term()].
flatten(List) when is_list(List) ->
do_flatten(List, []).
--spec flatten([term()], [term()]) -> [term()].
+-spec flatten(DeepList, Tail) -> List when
+ DeepList :: [term() | DeepList],
+ Tail :: [term()],
+ List :: [term()].
flatten(List, Tail) when is_list(List), is_list(Tail) ->
do_flatten(List, Tail).
@@ -440,7 +568,8 @@ do_flatten([], Tail) ->
%% flatlength(List)
%% Calculate the length of a list of lists.
--spec flatlength([term()]) -> non_neg_integer().
+-spec flatlength(DeepList) -> non_neg_integer() when
+ DeepList :: [term() | DeepList].
flatlength(List) ->
flatlength(List, 0).
@@ -481,7 +610,12 @@ flatlength([], L) -> L.
% keysearch3(Key, N, T);
%keysearch3(Key, N, []) -> false.
--spec keydelete(term(), pos_integer(), [T]) -> [T] when T :: tuple().
+-spec keydelete(Key, N, TupleList1) -> TupleList2 when
+ Key :: term(),
+ N :: pos_integer(),
+ TupleList1 :: [Tuple],
+ TupleList2 :: [Tuple],
+ Tuple :: tuple().
keydelete(K, N, L) when is_integer(N), N > 0 ->
keydelete3(K, N, L).
@@ -491,7 +625,12 @@ keydelete3(Key, N, [H|T]) ->
[H|keydelete3(Key, N, T)];
keydelete3(_, _, []) -> [].
--spec keyreplace(term(), pos_integer(), [tuple()], tuple()) -> [tuple()].
+-spec keyreplace(Key, N, TupleList1, NewTuple) -> TupleList2 when
+ Key :: term(),
+ N :: pos_integer(),
+ TupleList1 :: [tuple()],
+ TupleList2 :: [tuple()],
+ NewTuple :: tuple().
keyreplace(K, N, L, New) when is_integer(N), N > 0, is_tuple(New) ->
keyreplace3(K, N, L, New).
@@ -502,8 +641,12 @@ keyreplace3(Key, Pos, [H|T], New) ->
[H|keyreplace3(Key, Pos, T, New)];
keyreplace3(_, _, [], _) -> [].
--spec keytake(term(), pos_integer(), [tuple()]) ->
- {'value', tuple(), [tuple()]} | 'false'.
+-spec keytake(Key, N, TupleList1) -> {value, Tuple, TupleList2} | false when
+ Key :: term(),
+ N :: pos_integer(),
+ TupleList1 :: [tuple()],
+ TupleList2 :: [tuple()],
+ Tuple :: tuple().
keytake(Key, N, L) when is_integer(N), N > 0 ->
keytake(Key, N, L, []).
@@ -514,7 +657,12 @@ keytake(Key, N, [H|T], L) ->
keytake(Key, N, T, [H|L]);
keytake(_K, _N, [], _L) -> false.
--spec keystore(term(), pos_integer(), [tuple()], tuple()) -> [tuple(),...].
+-spec keystore(Key, N, TupleList1, NewTuple) -> TupleList2 when
+ Key :: term(),
+ N :: pos_integer(),
+ TupleList1 :: [tuple()],
+ TupleList2 :: [tuple(), ...],
+ NewTuple :: tuple().
keystore(K, N, L, New) when is_integer(N), N > 0, is_tuple(New) ->
keystore2(K, N, L, New).
@@ -526,7 +674,11 @@ keystore2(Key, N, [H|T], New) ->
keystore2(_Key, _N, [], New) ->
[New].
--spec keysort(pos_integer(), [T]) -> [T] when T :: tuple().
+-spec keysort(N, TupleList1) -> TupleList2 when
+ N :: pos_integer(),
+ TupleList1 :: [Tuple],
+ TupleList2 :: [Tuple],
+ Tuple :: tuple().
keysort(I, L) when is_integer(I), I > 0 ->
case L of
@@ -583,8 +735,13 @@ keysort_1(I, X, EX, [Y | L], R) ->
keysort_1(_I, X, _EX, [], R) ->
lists:reverse(R, [X]).
--spec keymerge(pos_integer(), [X], [Y]) ->
- [R] when X :: tuple(), Y :: tuple(), R :: tuple().
+-spec keymerge(N, TupleList1, TupleList2) -> TupleList3 when
+ N :: pos_integer(),
+ TupleList1 :: [T1],
+ TupleList2 :: [T2],
+ TupleList3 :: [(T1 | T2)],
+ T1 :: tuple(),
+ T2 :: tuple().
keymerge(Index, T1, L2) when is_integer(Index), Index > 0 ->
case L2 of
@@ -611,7 +768,11 @@ rkeymerge(Index, T1, L2) when is_integer(Index), Index > 0 ->
lists:reverse(M, [])
end.
--spec ukeysort(pos_integer(), [T]) -> [T] when T :: tuple().
+-spec ukeysort(N, TupleList1) -> TupleList2 when
+ N :: pos_integer(),
+ TupleList1 :: [Tuple],
+ TupleList2 :: [Tuple],
+ Tuple :: tuple().
ukeysort(I, L) when is_integer(I), I > 0 ->
case L of
@@ -676,8 +837,13 @@ ukeysort_1(I, X, EX, [Y | L]) ->
ukeysort_1(_I, X, _EX, []) ->
[X].
--spec ukeymerge(pos_integer(), [X], [Y]) ->
- [(X | Y)] when X :: tuple(), Y :: tuple().
+-spec ukeymerge(N, TupleList1, TupleList2) -> TupleList3 when
+ N :: pos_integer(),
+ TupleList1 :: [T1],
+ TupleList2 :: [T2],
+ TupleList3 :: [(T1 | T2)],
+ T1 :: tuple(),
+ T2 :: tuple().
ukeymerge(Index, L1, T2) when is_integer(Index), Index > 0 ->
case L1 of
@@ -704,7 +870,11 @@ rukeymerge(Index, T1, L2) when is_integer(Index), Index > 0 ->
lists:reverse(M, [])
end.
--spec keymap(fun((term()) -> term()), pos_integer(), [tuple()]) -> [tuple()].
+-spec keymap(Fun, N, TupleList1) -> TupleList2 when
+ Fun :: fun((Term1 :: term()) -> Term2 :: term()),
+ N :: pos_integer(),
+ TupleList1 :: [tuple()],
+ TupleList2 :: [tuple()].
keymap(Fun, Index, [Tup|Tail]) ->
[setelement(Index, Tup, Fun(element(Index, Tup)))|keymap(Fun, Index, Tail)];
@@ -713,7 +883,11 @@ keymap(Fun, Index, []) when is_integer(Index), Index >= 1,
%%% Suggestion from OTP-2948: sort and merge with Fun.
--spec sort(fun((T, T) -> boolean()), [T]) -> [T].
+-spec sort(Fun, List1) -> List2 when
+ Fun :: fun((A :: T, B :: T) -> boolean()),
+ List1 :: [T],
+ List2 :: [T],
+ T :: term().
sort(Fun, []) when is_function(Fun, 2) ->
[];
@@ -727,7 +901,13 @@ sort(Fun, [X, Y | T]) ->
fsplit_2(Y, X, Fun, T, [], [])
end.
--spec merge(fun((X, Y) -> boolean()), [X], [Y]) -> [(X | Y)].
+-spec merge(Fun, List1, List2) -> List3 when
+ Fun :: fun((A, B) -> boolean()),
+ List1 :: [A],
+ List2 :: [B],
+ List3 :: [(A | B)],
+ A :: term(),
+ B :: term().
merge(Fun, T1, [H2 | T2]) when is_function(Fun, 2) ->
lists:reverse(fmerge2_1(T1, H2, Fun, T2, []), []);
@@ -743,7 +923,11 @@ rmerge(Fun, T1, [H2 | T2]) when is_function(Fun, 2) ->
rmerge(Fun, T1, []) when is_function(Fun, 2) ->
T1.
--spec usort(fun((T, T) -> boolean()), [T]) -> [T].
+-spec usort(Fun, List1) -> List2 when
+ Fun :: fun((T, T) -> boolean()),
+ List1 :: [T],
+ List2 :: [T],
+ T :: term().
usort(Fun, [_] = L) when is_function(Fun, 2) ->
L;
@@ -770,7 +954,13 @@ usort_1(Fun, X, [Y | L]) ->
ufsplit_2(Y, L, Fun, [X])
end.
--spec umerge(fun((X, Y) -> boolean()), [X], [Y]) -> [(X | Y)].
+-spec umerge(Fun, List1, List2) -> List3 when
+ Fun :: fun((A, B) -> boolean()),
+ List1 :: [A],
+ List2 :: [B],
+ List3 :: [(A | B)],
+ A :: term(),
+ B :: term().
umerge(Fun, [], T2) when is_function(Fun, 2) ->
T2;
@@ -789,7 +979,10 @@ rumerge(Fun, T1, [H2 | T2]) when is_function(Fun, 2) ->
%% usort(List) -> L
%% sorts the list L, removes duplicates
--spec usort([T]) -> [T].
+-spec usort(List1) -> List2 when
+ List1 :: [T],
+ List2 :: [T],
+ T :: term().
usort([X, Y | L] = L0) when X < Y ->
case L of
@@ -844,7 +1037,11 @@ usort_1(X, []) ->
%% umerge(List) -> L
%% merges a list of sorted lists without duplicates, removes duplicates
--spec umerge([[T]]) -> [T].
+-spec umerge(ListOfLists) -> List1 when
+ ListOfLists :: [List],
+ List :: [T],
+ List1 :: [T],
+ T :: term().
umerge(L) ->
umergel(L).
@@ -853,7 +1050,14 @@ umerge(L) ->
%% merges three sorted lists X, Y and Z without duplicates,
%% removes duplicates
--spec umerge3([X], [Y], [Z]) -> [(X | Y | Z)].
+-spec umerge3(List1, List2, List3) -> List4 when
+ List1 :: [X],
+ List2 :: [Y],
+ List3 :: [Z],
+ List4 :: [(X | Y | Z)],
+ X :: term(),
+ Y :: term(),
+ Z :: term().
umerge3(L1, [], L3) ->
umerge(L1, L3);
@@ -878,7 +1082,12 @@ rumerge3(L1, [H2 | T2], [H3 | T3]) ->
%% umerge(X, Y) -> L
%% merges two sorted lists X and Y without duplicates, removes duplicates
--spec umerge([X], [Y]) -> [(X | Y)].
+-spec umerge(List1, List2) -> List3 when
+ List1 :: [X],
+ List2 :: [Y],
+ List3 :: [(X | Y)],
+ X :: term(),
+ Y :: term().
umerge([], T2) ->
T2;
@@ -924,7 +1133,10 @@ rumerge(T1, [H2 | T2]) ->
%% There are also versions with an extra argument, ExtraArgs, which is a
%% list of extra arguments to each call.
--spec all(fun((T) -> boolean()), [T]) -> boolean().
+-spec all(Pred, List) -> boolean() when
+ Pred :: fun((Elem :: T) -> boolean()),
+ List :: [T],
+ T :: term().
all(Pred, [Hd|Tail]) ->
case Pred(Hd) of
@@ -933,7 +1145,10 @@ all(Pred, [Hd|Tail]) ->
end;
all(Pred, []) when is_function(Pred, 1) -> true.
--spec any(fun((T) -> boolean()), [T]) -> boolean().
+-spec any(Pred, List) -> boolean() when
+ Pred :: fun((Elem :: T) -> boolean()),
+ List :: [T],
+ T :: term().
any(Pred, [Hd|Tail]) ->
case Pred(Hd) of
@@ -942,31 +1157,59 @@ any(Pred, [Hd|Tail]) ->
end;
any(Pred, []) when is_function(Pred, 1) -> false.
--spec map(fun((D) -> R), [D]) -> [R].
+-spec map(Fun, List1) -> List2 when
+ Fun :: fun((A) -> B),
+ List1 :: [A],
+ List2 :: [B],
+ A :: term(),
+ B :: term().
map(F, [H|T]) ->
[F(H)|map(F, T)];
map(F, []) when is_function(F, 1) -> [].
--spec flatmap(fun((D) -> [R]), [D]) -> [R].
+-spec flatmap(Fun, List1) -> List2 when
+ Fun :: fun((A) -> [B]),
+ List1 :: [A],
+ List2 :: [B],
+ A :: term(),
+ B :: term().
flatmap(F, [Hd|Tail]) ->
F(Hd) ++ flatmap(F, Tail);
flatmap(F, []) when is_function(F, 1) -> [].
--spec foldl(fun((T, term()) -> term()), term(), [T]) -> term().
+-spec foldl(Fun, Acc0, List) -> Acc1 when
+ Fun :: fun((Elem :: T, AccIn) -> AccOut),
+ Acc0 :: term(),
+ Acc1 :: term(),
+ AccIn :: term(),
+ AccOut :: term(),
+ List :: [T],
+ T :: term().
foldl(F, Accu, [Hd|Tail]) ->
foldl(F, F(Hd, Accu), Tail);
foldl(F, Accu, []) when is_function(F, 2) -> Accu.
--spec foldr(fun((T, term()) -> term()), term(), [T]) -> term().
+-spec foldr(Fun, Acc0, List) -> Acc1 when
+ Fun :: fun((Elem :: T, AccIn) -> AccOut),
+ Acc0 :: term(),
+ Acc1 :: term(),
+ AccIn :: term(),
+ AccOut :: term(),
+ List :: [T],
+ T :: term().
foldr(F, Accu, [Hd|Tail]) ->
F(Hd, foldr(F, Accu, Tail));
foldr(F, Accu, []) when is_function(F, 2) -> Accu.
--spec filter(Pred :: fun((T) -> boolean()), List :: [T]) -> [T].
+-spec filter(Pred, List1) -> List2 when
+ Pred :: fun((Elem :: T) -> boolean()),
+ List1 :: [T],
+ List2 :: [T],
+ T :: term().
filter(Pred, List) when is_function(Pred, 1) ->
[ E || E <- List, Pred(E) ].
@@ -974,7 +1217,12 @@ filter(Pred, List) when is_function(Pred, 1) ->
%% Equivalent to {filter(F, L), filter(NotF, L)}, if NotF = 'fun(X) ->
%% not F(X) end'.
--spec partition(Pred :: fun((T) -> boolean()), List :: [T]) -> {[T], [T]}.
+-spec partition(Pred, List) -> {Satisfying, NotSatisfying} when
+ Pred :: fun((Elem :: T) -> boolean()),
+ List :: [T],
+ Satisfying :: [T],
+ NotSatisfying :: [T],
+ T :: term().
partition(Pred, L) ->
partition(Pred, L, [], []).
@@ -1000,14 +1248,26 @@ zf(F, [Hd|Tail]) ->
end;
zf(F, []) when is_function(F, 1) -> [].
--spec foreach(F :: fun((T) -> term()), List :: [T]) -> 'ok'.
+-spec foreach(Fun, List) -> ok when
+ Fun :: fun((Elem :: T) -> term()),
+ List :: [T],
+ T :: term().
foreach(F, [Hd|Tail]) ->
F(Hd),
foreach(F, Tail);
foreach(F, []) when is_function(F, 1) -> ok.
--spec mapfoldl(fun((A, term()) -> {B, term()}), term(), [A]) -> {[B], term()}.
+-spec mapfoldl(Fun, Acc0, List1) -> {List2, Acc1} when
+ Fun :: fun((A, AccIn) -> {B, AccOut}),
+ Acc0 :: term(),
+ Acc1 :: term(),
+ AccIn :: term(),
+ AccOut :: term(),
+ List1 :: [A],
+ List2 :: [B],
+ A :: term(),
+ B :: term().
mapfoldl(F, Accu0, [Hd|Tail]) ->
{R,Accu1} = F(Hd, Accu0),
@@ -1015,7 +1275,16 @@ mapfoldl(F, Accu0, [Hd|Tail]) ->
{[R|Rs],Accu2};
mapfoldl(F, Accu, []) when is_function(F, 2) -> {[],Accu}.
--spec mapfoldr(fun((A, term()) -> {B, term()}), term(), [A]) -> {[B], term()}.
+-spec mapfoldr(Fun, Acc0, List1) -> {List2, Acc1} when
+ Fun :: fun((A, AccIn) -> {B, AccOut}),
+ Acc0 :: term(),
+ Acc1 :: term(),
+ AccIn :: term(),
+ AccOut :: term(),
+ List1 :: [A],
+ List2 :: [B],
+ A :: term(),
+ B :: term().
mapfoldr(F, Accu0, [Hd|Tail]) ->
{Rs,Accu1} = mapfoldr(F, Accu0, Tail),
@@ -1023,7 +1292,11 @@ mapfoldr(F, Accu0, [Hd|Tail]) ->
{[R|Rs],Accu2};
mapfoldr(F, Accu, []) when is_function(F, 2) -> {[],Accu}.
--spec takewhile(fun((T) -> boolean()), [T]) -> [T].
+-spec takewhile(Pred, List1) -> List2 when
+ Pred :: fun((Elem :: T) -> boolean()),
+ List1 :: [T],
+ List2 :: [T],
+ T :: term().
takewhile(Pred, [Hd|Tail]) ->
case Pred(Hd) of
@@ -1032,7 +1305,11 @@ takewhile(Pred, [Hd|Tail]) ->
end;
takewhile(Pred, []) when is_function(Pred, 1) -> [].
--spec dropwhile(fun((T) -> boolean()), [T]) -> [T].
+-spec dropwhile(Pred, List1) -> List2 when
+ Pred :: fun((Elem :: T) -> boolean()),
+ List1 :: [T],
+ List2 :: [T],
+ T :: term().
dropwhile(Pred, [Hd|Tail]=Rest) ->
case Pred(Hd) of
@@ -1041,7 +1318,12 @@ dropwhile(Pred, [Hd|Tail]=Rest) ->
end;
dropwhile(Pred, []) when is_function(Pred, 1) -> [].
--spec splitwith(fun((T) -> boolean()), [T]) -> {[T], [T]}.
+-spec splitwith(Pred, List) -> {List1, List2} when
+ Pred :: fun((T) -> boolean()),
+ List :: [T],
+ List1 :: [T],
+ List2 :: [T],
+ T :: term().
splitwith(Pred, List) when is_function(Pred, 1) ->
splitwith(Pred, List, []).
@@ -1054,7 +1336,12 @@ splitwith(Pred, [Hd|Tail], Taken) ->
splitwith(Pred, [], Taken) when is_function(Pred, 1) ->
{reverse(Taken),[]}.
--spec split(non_neg_integer(), [T]) -> {[T], [T]}.
+-spec split(N, List1) -> {List2, List3} when
+ N :: non_neg_integer(),
+ List1 :: [T],
+ List2 :: [T],
+ List3 :: [T],
+ T :: term().
split(N, List) when is_integer(N), N >= 0, is_list(List) ->
case split(N, List, []) of
diff --git a/lib/stdlib/src/log_mf_h.erl b/lib/stdlib/src/log_mf_h.erl
index 5fa5360fa1..f7f128dac7 100644
--- a/lib/stdlib/src/log_mf_h.erl
+++ b/lib/stdlib/src/log_mf_h.erl
@@ -27,14 +27,13 @@
%%-----------------------------------------------------------------
--type dir() :: file:filename().
-type b() :: non_neg_integer().
-type f() :: 1..255.
-type pred() :: fun((term()) -> boolean()).
%%-----------------------------------------------------------------
--record(state, {dir :: dir(),
+-record(state, {dir :: file:filename(),
maxB :: b(),
maxF :: f(),
curB :: b(),
@@ -67,11 +66,23 @@
%% EventMgr = pid() | atom().
%%-----------------------------------------------------------------
--spec init(dir(), b(), f()) -> {dir(), b(), f(), pred()}.
+-opaque args() :: {file:filename(), b(), f(), pred()}.
+
+
+-spec init(Dir, MaxBytes, MaxFiles) -> Args when
+ Dir :: file:filename(),
+ MaxBytes :: non_neg_integer(), % b()
+ MaxFiles :: 1..255, % f()
+ Args :: args().
init(Dir, MaxB, MaxF) -> init(Dir, MaxB, MaxF, fun(_) -> true end).
--spec init(dir(), b(), f(), pred()) -> {dir(), b(), f(), pred()}.
+-spec init(Dir, MaxBytes, MaxFiles, Pred) -> Args when
+ Dir :: file:filename(),
+ MaxBytes :: non_neg_integer(), % b()
+ MaxFiles :: 1..255, % f()
+ Pred :: fun((Event :: term()) -> boolean()), % pred()
+ Args :: args().
init(Dir, MaxB, MaxF, Pred) -> {Dir, MaxB, MaxF, Pred}.
@@ -79,7 +90,7 @@ init(Dir, MaxB, MaxF, Pred) -> {Dir, MaxB, MaxF, Pred}.
%% Call-back functions from gen_event
%%-----------------------------------------------------------------
--spec init({dir(), b(), f(), pred()}) -> {'ok', #state{}} | {'error', term()}.
+-spec init({file:filename(), non_neg_integer(), f(), pred()}) -> {'ok', #state{}} | {'error', term()}.
init({Dir, MaxB, MaxF, Pred}) when is_integer(MaxF), MaxF > 0, MaxF < 256 ->
First =
diff --git a/lib/stdlib/src/ms_transform.erl b/lib/stdlib/src/ms_transform.erl
index b565eb20f4..48e22e53fa 100644
--- a/lib/stdlib/src/ms_transform.erl
+++ b/lib/stdlib/src/ms_transform.erl
@@ -66,6 +66,11 @@
%%
%% Called by compiler or ets/dbg:fun2ms when errors/warnings occur
%%
+
+-spec(format_error(Error) -> Chars when
+ Error :: {error, module(), term()},
+ Chars :: io_lib:chars()).
+
format_error({?WARN_SHADOW_VAR,Name}) ->
lists:flatten(
io_lib:format("variable ~p shadowed in ms_transform fun head",
@@ -186,6 +191,12 @@ format_error(Else) ->
%%
%% Called when translating in shell
%%
+
+-spec transform_from_shell(Dialect, Clauses, BoundEnvironment) -> term() when
+ Dialect :: ets | dbg,
+ Clauses :: [erl_parse:abstract_clause()],
+ BoundEnvironment :: erl_eval:binding_struct().
+
transform_from_shell(Dialect, Clauses, BoundEnvironment) ->
SaveFilename = setup_filename(),
case catch ms_clause_list(1,Clauses,Dialect,gb_sets:new()) of
@@ -211,6 +222,11 @@ transform_from_shell(Dialect, Clauses, BoundEnvironment) ->
%%
%% Called when translating during compiling
%%
+
+-spec parse_transform(Forms, Options) -> Forms when
+ Forms :: [erl_parse:abstract_form()],
+ Options :: term().
+
parse_transform(Forms, _Options) ->
SaveFilename = setup_filename(),
%io:format("Forms: ~p~n",[Forms]),
diff --git a/lib/stdlib/src/orddict.erl b/lib/stdlib/src/orddict.erl
index 4e30c9eefd..45d3c84b3e 100644
--- a/lib/stdlib/src/orddict.erl
+++ b/lib/stdlib/src/orddict.erl
@@ -25,9 +25,11 @@
-export([store/3,append/3,append_list/3,update/3,update/4,update_counter/3]).
-export([fold/3,map/2,filter/2,merge/3]).
+-export_type([orddict/0]).
+
%%---------------------------------------------------------------------------
--type orddict() :: [{term(), term()}].
+-type orddict() :: [{Key :: term(), Value :: term()}].
%%---------------------------------------------------------------------------
@@ -35,45 +37,63 @@
new() -> [].
--spec is_key(Key::term(), Dictionary::orddict()) -> boolean().
+-spec is_key(Key, Orddict) -> boolean() when
+ Key :: term(),
+ Orddict :: orddict().
is_key(Key, [{K,_}|_]) when Key < K -> false;
is_key(Key, [{K,_}|Dict]) when Key > K -> is_key(Key, Dict);
is_key(_Key, [{_K,_Val}|_]) -> true; %Key == K
is_key(_, []) -> false.
--spec to_list(orddict()) -> [{term(), term()}].
+-spec to_list(Orddict) -> List when
+ Orddict :: orddict(),
+ List :: [{Key :: term(), Value :: term()}].
to_list(Dict) -> Dict.
--spec from_list([{term(), term()}]) -> orddict().
+-spec from_list(List) -> Orddict when
+ List :: [{Key :: term(), Value :: term()}],
+ Orddict :: orddict().
from_list(Pairs) ->
lists:foldl(fun ({K,V}, D) -> store(K, V, D) end, [], Pairs).
--spec size(orddict()) -> non_neg_integer().
+-spec size(Orddict) -> non_neg_integer() when
+ Orddict :: orddict().
size(D) -> length(D).
--spec fetch(Key::term(), Dictionary::orddict()) -> term().
+-spec fetch(Key, Orddict) -> Value when
+ Key :: term(),
+ Value :: term(),
+ Orddict :: orddict().
fetch(Key, [{K,_}|D]) when Key > K -> fetch(Key, D);
fetch(Key, [{K,Value}|_]) when Key == K -> Value.
--spec find(Key::term(), Dictionary::orddict()) -> {'ok', term()} | 'error'.
+-spec find(Key, Orddict) -> {'ok', Value} | 'error' when
+ Key :: term(),
+ Orddict :: orddict(),
+ Value :: term().
find(Key, [{K,_}|_]) when Key < K -> error;
find(Key, [{K,_}|D]) when Key > K -> find(Key, D);
find(_Key, [{_K,Value}|_]) -> {ok,Value}; %Key == K
find(_, []) -> error.
--spec fetch_keys(Dictionary::orddict()) -> [term()].
+-spec fetch_keys(Orddict) -> Keys when
+ Orddict :: orddict(),
+ Keys :: [term()].
fetch_keys([{Key,_}|Dict]) ->
[Key|fetch_keys(Dict)];
fetch_keys([]) -> [].
--spec erase(Key::term(), Dictionary::orddict()) -> orddict().
+-spec erase(Key, Orddict1) -> Orddict2 when
+ Key :: term(),
+ Orddict1 :: orddict(),
+ Orddict2 :: orddict().
erase(Key, [{K,_}=E|Dict]) when Key < K -> [E|Dict];
erase(Key, [{K,_}=E|Dict]) when Key > K ->
@@ -81,7 +101,11 @@ erase(Key, [{K,_}=E|Dict]) when Key > K ->
erase(_Key, [{_K,_Val}|Dict]) -> Dict; %Key == K
erase(_, []) -> [].
--spec store(Key::term(), Value::term(), Dictionary::orddict()) -> orddict().
+-spec store(Key, Value, Orddict1) -> Orddict2 when
+ Key :: term(),
+ Value :: term(),
+ Orddict1 :: orddict(),
+ Orddict2 :: orddict().
store(Key, New, [{K,_}=E|Dict]) when Key < K ->
[{Key,New},E|Dict];
@@ -91,7 +115,11 @@ store(Key, New, [{_K,_Old}|Dict]) -> %Key == K
[{Key,New}|Dict];
store(Key, New, []) -> [{Key,New}].
--spec append(Key::term(), Value::term(), Dictionary::orddict()) -> orddict().
+-spec append(Key, Value, Orddict1) -> Orddict2 when
+ Key :: term(),
+ Value :: term(),
+ Orddict1 :: orddict(),
+ Orddict2 :: orddict().
append(Key, New, [{K,_}=E|Dict]) when Key < K ->
[{Key,[New]},E|Dict];
@@ -101,7 +129,11 @@ append(Key, New, [{_K,Old}|Dict]) -> %Key == K
[{Key,Old ++ [New]}|Dict];
append(Key, New, []) -> [{Key,[New]}].
--spec append_list(Key::term(), ValueList::[term()], orddict()) -> orddict().
+-spec append_list(Key, ValList, Orddict1) -> Orddict2 when
+ Key :: term(),
+ ValList :: [Value :: term()],
+ Orddict1 :: orddict(),
+ Orddict2 :: orddict().
append_list(Key, NewList, [{K,_}=E|Dict]) when Key < K ->
[{Key,NewList},E|Dict];
@@ -112,14 +144,23 @@ append_list(Key, NewList, [{_K,Old}|Dict]) -> %Key == K
append_list(Key, NewList, []) ->
[{Key,NewList}].
--spec update(Key::term(), Fun::fun((term()) -> term()), orddict()) -> orddict().
+-spec update(Key, Fun, Orddict1) -> Orddict2 when
+ Key :: term(),
+ Fun :: fun((Value1 :: term()) -> Value2 :: term()),
+ Orddict1 :: orddict(),
+ Orddict2 :: orddict().
update(Key, Fun, [{K,_}=E|Dict]) when Key > K ->
[E|update(Key, Fun, Dict)];
update(Key, Fun, [{K,Val}|Dict]) when Key == K ->
[{Key,Fun(Val)}|Dict].
--spec update(term(), fun((term()) -> term()), term(), orddict()) -> orddict().
+-spec update(Key, Fun, Initial, Orddict1) -> Orddict2 when
+ Key :: term(),
+ Initial :: term(),
+ Fun :: fun((Value1 :: term()) -> Value2 :: term()),
+ Orddict1 :: orddict(),
+ Orddict2 :: orddict().
update(Key, _, Init, [{K,_}=E|Dict]) when Key < K ->
[{Key,Init},E|Dict];
@@ -129,7 +170,11 @@ update(Key, Fun, _Init, [{_K,Val}|Dict]) -> %Key == K
[{Key,Fun(Val)}|Dict];
update(Key, _, Init, []) -> [{Key,Init}].
--spec update_counter(Key::term(), Incr::number(), orddict()) -> orddict().
+-spec update_counter(Key, Increment, Orddict1) -> Orddict2 when
+ Key :: term(),
+ Increment :: number(),
+ Orddict1 :: orddict(),
+ Orddict2 :: orddict().
update_counter(Key, Incr, [{K,_}=E|Dict]) when Key < K ->
[{Key,Incr},E|Dict];
@@ -139,19 +184,29 @@ update_counter(Key, Incr, [{_K,Val}|Dict]) -> %Key == K
[{Key,Val+Incr}|Dict];
update_counter(Key, Incr, []) -> [{Key,Incr}].
--spec fold(fun((term(),term(),term()) -> term()), term(), orddict()) -> term().
+-spec fold(Fun, Acc0, Orddict) -> Acc1 when
+ Fun :: fun((Key :: term(), Value :: term(), AccIn :: term()) -> AccOut :: term()),
+ Acc0 :: term(),
+ Acc1 :: term(),
+ Orddict :: orddict().
fold(F, Acc, [{Key,Val}|D]) ->
fold(F, F(Key, Val, Acc), D);
fold(F, Acc, []) when is_function(F, 3) -> Acc.
--spec map(fun((term(), term()) -> term()), orddict()) -> orddict().
+-spec map(Fun, Orddict1) -> Orddict2 when
+ Fun :: fun((Key :: term(), Value1 :: term()) -> Value2 :: term()),
+ Orddict1 :: orddict(),
+ Orddict2 :: orddict().
map(F, [{Key,Val}|D]) ->
[{Key,F(Key, Val)}|map(F, D)];
map(F, []) when is_function(F, 2) -> [].
--spec filter(fun((term(), term()) -> boolean()), orddict()) -> orddict().
+-spec filter(Pred, Orddict1) -> Orddict2 when
+ Pred :: fun((Key :: term(), Value :: term()) -> boolean()),
+ Orddict1 :: orddict(),
+ Orddict2 :: orddict().
filter(F, [{Key,Val}=E|D]) ->
case F(Key, Val) of
@@ -160,8 +215,11 @@ filter(F, [{Key,Val}=E|D]) ->
end;
filter(F, []) when is_function(F, 2) -> [].
--spec merge(fun((term(), term(), term()) -> term()), orddict(), orddict()) ->
- orddict().
+-spec merge(Fun, Orddict1, Orddict2) -> Orddict3 when
+ Fun :: fun((Key :: term(), Value1 :: term(), Value2 :: term()) -> Value :: term()),
+ Orddict1 :: orddict(),
+ Orddict2 :: orddict(),
+ Orddict3 :: orddict().
merge(F, [{K1,_}=E1|D1], [{K2,_}=E2|D2]) when K1 < K2 ->
[E1|merge(F, D1, [E2|D2])];
diff --git a/lib/stdlib/src/ordsets.erl b/lib/stdlib/src/ordsets.erl
index 5a1c260703..4a8b1275b2 100644
--- a/lib/stdlib/src/ordsets.erl
+++ b/lib/stdlib/src/ordsets.erl
@@ -40,7 +40,8 @@ new() -> [].
%% is_set(Term) -> boolean().
%% Return 'true' if Set is an ordered set of elements, else 'false'.
--spec is_set(term()) -> boolean().
+-spec is_set(Ordset) -> boolean() when
+ Ordset :: term().
is_set([E|Es]) -> is_set(Es, E);
is_set([]) -> true;
@@ -54,21 +55,26 @@ is_set([], _) -> true.
%% size(OrdSet) -> int().
%% Return the number of elements in OrdSet.
--spec size(ordset(_)) -> non_neg_integer().
+-spec size(Ordset) -> non_neg_integer() when
+ Ordset :: ordset(_).
size(S) -> length(S).
%% to_list(OrdSet) -> [Elem].
%% Return the elements in OrdSet as a list.
--spec to_list(ordset(T)) -> [T].
+-spec to_list(Ordset) -> List when
+ Ordset :: ordset(T),
+ List :: [T].
to_list(S) -> S.
%% from_list([Elem]) -> Set.
%% Build an ordered set from the elements in List.
--spec from_list([T]) -> ordset(T).
+-spec from_list(List) -> Ordset when
+ List :: [T],
+ Ordset :: ordset(T).
from_list(L) ->
lists:usort(L).
@@ -76,7 +82,9 @@ from_list(L) ->
%% is_element(Element, OrdSet) -> boolean().
%% Return 'true' if Element is an element of OrdSet, else 'false'.
--spec is_element(term(), ordset(_)) -> boolean().
+-spec is_element(Element, Ordset) -> boolean() when
+ Element :: term(),
+ Ordset :: ordset(_).
is_element(E, [H|Es]) when E > H -> is_element(E, Es);
is_element(E, [H|_]) when E < H -> false;
@@ -86,7 +94,12 @@ is_element(_, []) -> false.
%% add_element(Element, OrdSet) -> OrdSet.
%% Return OrdSet with Element inserted in it.
--spec add_element(E, ordset(T)) -> [T | E,...].
+-spec add_element(Element, Ordset1) -> Ordset2 when
+ Element :: E,
+ Ordset1 :: ordset(T),
+ Ordset2 :: ordset(T | E).
+
+%-spec add_element(E, ordset(T)) -> [T | E,...].
add_element(E, [H|Es]) when E > H -> [H|add_element(E, Es)];
add_element(E, [H|_]=Set) when E < H -> [E|Set];
@@ -96,7 +109,10 @@ add_element(E, []) -> [E].
%% del_element(Element, OrdSet) -> OrdSet.
%% Return OrdSet but with Element removed.
--spec del_element(term(), ordset(T)) -> ordset(T).
+-spec del_element(Element, Ordset1) -> Ordset2 when
+ Element :: term(),
+ Ordset1 :: ordset(T),
+ Ordset2 :: ordset(T).
del_element(E, [H|Es]) when E > H -> [H|del_element(E, Es)];
del_element(E, [H|_]=Set) when E < H -> Set;
@@ -106,7 +122,10 @@ del_element(_, []) -> [].
%% union(OrdSet1, OrdSet2) -> OrdSet
%% Return the union of OrdSet1 and OrdSet2.
--spec union(ordset(T1), ordset(T2)) -> ordset(T1 | T2).
+-spec union(Ordset1, Ordset2) -> Ordset3 when
+ Ordset1 :: ordset(T1),
+ Ordset2 :: ordset(T2),
+ Ordset3 :: ordset(T1 | T2).
union([E1|Es1], [E2|_]=Set2) when E1 < E2 ->
[E1|union(Es1, Set2)];
@@ -120,7 +139,9 @@ union(Es1, []) -> Es1.
%% union([OrdSet]) -> OrdSet
%% Return the union of the list of ordered sets.
--spec union([ordset(T)]) -> ordset(T).
+-spec union(OrdsetList) -> Ordset when
+ OrdsetList :: [ordset(T)],
+ Ordset :: ordset(T).
union([S1,S2|Ss]) ->
union1(union(S1, S2), Ss);
@@ -133,7 +154,10 @@ union1(S1, []) -> S1.
%% intersection(OrdSet1, OrdSet2) -> OrdSet.
%% Return the intersection of OrdSet1 and OrdSet2.
--spec intersection(ordset(_), ordset(_)) -> ordset(_).
+-spec intersection(Ordset1, Ordset2) -> Ordset3 when
+ Ordset1 :: ordset(_),
+ Ordset2 :: ordset(_),
+ Ordset3 :: ordset(_).
intersection([E1|Es1], [E2|_]=Set2) when E1 < E2 ->
intersection(Es1, Set2);
@@ -149,7 +173,9 @@ intersection(_, []) ->
%% intersection([OrdSet]) -> OrdSet.
%% Return the intersection of the list of ordered sets.
--spec intersection([ordset(_),...]) -> ordset(_).
+-spec intersection(OrdsetList) -> Ordset when
+ OrdsetList :: [ordset(_),...],
+ Ordset :: ordset(_).
intersection([S1,S2|Ss]) ->
intersection1(intersection(S1, S2), Ss);
@@ -162,7 +188,9 @@ intersection1(S1, []) -> S1.
%% is_disjoint(OrdSet1, OrdSet2) -> boolean().
%% Check whether OrdSet1 and OrdSet2 are disjoint.
--spec is_disjoint(ordset(_), ordset(_)) -> boolean().
+-spec is_disjoint(Ordset1, Ordset2) -> boolean() when
+ Ordset1 :: ordset(_),
+ Ordset2 :: ordset(_).
is_disjoint([E1|Es1], [E2|_]=Set2) when E1 < E2 ->
is_disjoint(Es1, Set2);
@@ -179,7 +207,10 @@ is_disjoint(_, []) ->
%% Return all and only the elements of OrdSet1 which are not also in
%% OrdSet2.
--spec subtract(ordset(_), ordset(_)) -> ordset(_).
+-spec subtract(Ordset1, Ordset2) -> Ordset3 when
+ Ordset1 :: ordset(_),
+ Ordset2 :: ordset(_),
+ Ordset3 :: ordset(_).
subtract([E1|Es1], [E2|_]=Set2) when E1 < E2 ->
[E1|subtract(Es1, Set2)];
@@ -194,7 +225,9 @@ subtract(Es1, []) -> Es1.
%% Return 'true' when every element of OrdSet1 is also a member of
%% OrdSet2, else 'false'.
--spec is_subset(ordset(_), ordset(_)) -> boolean().
+-spec is_subset(Ordset1, Ordset2) -> boolean() when
+ Ordset1 :: ordset(_),
+ Ordset2 :: ordset(_).
is_subset([E1|_], [E2|_]) when E1 < E2 -> %E1 not in Set2
false;
@@ -208,7 +241,11 @@ is_subset(_, []) -> false.
%% fold(Fun, Accumulator, OrdSet) -> Accumulator.
%% Fold function Fun over all elements in OrdSet and return Accumulator.
--spec fold(fun((T, term()) -> term()), term(), ordset(T)) -> term().
+-spec fold(Function, Acc0, Ordset) -> Acc1 when
+ Function :: fun((Element :: T, AccIn :: term()) -> AccOut :: term()),
+ Ordset :: ordset(T),
+ Acc0 :: term(),
+ Acc1 :: term().
fold(F, Acc, Set) ->
lists:foldl(F, Acc, Set).
@@ -216,7 +253,10 @@ fold(F, Acc, Set) ->
%% filter(Fun, OrdSet) -> OrdSet.
%% Filter OrdSet with Fun.
--spec filter(fun((T) -> boolean()), ordset(T)) -> ordset(T).
+-spec filter(Pred, Ordset1) -> Ordset2 when
+ Pred :: fun((Element :: T) -> boolean()),
+ Ordset1 :: ordset(T),
+ Ordset2 :: ordset(T).
filter(F, Set) ->
lists:filter(F, Set).
diff --git a/lib/stdlib/src/pg.erl b/lib/stdlib/src/pg.erl
index 503654e706..ee177e4e0b 100644
--- a/lib/stdlib/src/pg.erl
+++ b/lib/stdlib/src/pg.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -35,7 +35,9 @@
%% Create a brand new empty process group with the master residing
%% at the local node
--spec create(term()) -> 'ok' | {'error', term()}.
+-spec create(PgName) -> 'ok' | {'error', Reason} when
+ PgName :: term(),
+ Reason :: 'already_created' | term().
create(PgName) ->
catch begin check(PgName),
@@ -46,7 +48,10 @@ create(PgName) ->
%% Create a brand new empty process group with the master
%% residing at Node
--spec create(term(), node()) -> 'ok' | {'error', term()}.
+-spec create(PgName, Node) -> 'ok' | {'error', Reason} when
+ PgName :: term(),
+ Node :: node(),
+ Reason :: 'already_created' | term().
create(PgName, Node) ->
catch begin check(PgName),
@@ -66,7 +71,10 @@ standby(_PgName, _Node) ->
%% Tell process group PgName that Pid is a new member of the group
%% synchronously return a list of all old members in the group
--spec join(atom(), pid()) -> [pid()].
+-spec join(PgName, Pid) -> Members when
+ PgName :: term(),
+ Pid :: pid(),
+ Members :: [pid()].
join(PgName, Pid) when is_atom(PgName) ->
global:send(PgName, {join,self(),Pid}),
@@ -77,7 +85,9 @@ join(PgName, Pid) when is_atom(PgName) ->
%% Multi cast Mess to all members in the group
--spec send(atom() | pid(), term()) -> 'ok'.
+-spec send(PgName, Msg) -> 'ok' when
+ PgName :: term(),
+ Msg :: term().
send(PgName, Mess) when is_atom(PgName) ->
global:send(PgName, {send, self(), Mess}),
@@ -89,7 +99,9 @@ send(Pg, Mess) when is_pid(Pg) ->
%% multi cast a message to all members in the group but ourselves
%% If we are a member
--spec esend(atom() | pid(), term()) -> 'ok'.
+-spec esend(PgName, Msg) -> 'ok' when
+ PgName :: term(),
+ Msg :: term().
esend(PgName, Mess) when is_atom(PgName) ->
global:send(PgName, {esend,self(),Mess}),
@@ -100,7 +112,9 @@ esend(Pg, Mess) when is_pid(Pg) ->
%% Return the members of the group
--spec members(atom() | pid()) -> [pid()].
+-spec members(PgName) -> Members when
+ PgName :: term(),
+ Members :: [pid()].
members(PgName) when is_atom(PgName) ->
global:send(PgName, {self() ,members}),
diff --git a/lib/stdlib/src/pool.erl b/lib/stdlib/src/pool.erl
index a3c9927ee9..a5eb191ab2 100644
--- a/lib/stdlib/src/pool.erl
+++ b/lib/stdlib/src/pool.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -52,11 +52,16 @@
%% Start up using the .hosts.erlang file
--spec start(atom()) -> [node()].
+-spec start(Name) -> Nodes when
+ Name :: atom(),
+ Nodes :: [node()].
start(Name) ->
start(Name,[]).
--spec start(atom(), string()) -> [node()].
+-spec start(Name, Args) -> Nodes when
+ Name :: atom(),
+ Args :: string(),
+ Nodes :: [node()].
start(Name, Args) when is_atom(Name) ->
gen_server:start({global, pool_master}, pool, [], []),
Hosts = net_adm:host_file(),
@@ -71,7 +76,8 @@ start(Name, Args) when is_atom(Name) ->
get_nodes() ->
get_elements(2, get_nodes_and_load()).
--spec attach(node()) -> 'already_attached' | 'attached'.
+-spec attach(Node) -> 'already_attached' | 'attached' when
+ Node :: node().
attach(Node) ->
gen_server:call({global, pool_master}, {attach, Node}).
@@ -82,11 +88,17 @@ get_nodes_and_load() ->
get_node() ->
gen_server:call({global, pool_master}, get_node).
--spec pspawn(module(), atom(), [term()]) -> pid().
+-spec pspawn(Mod, Fun, Args) -> pid() when
+ Mod :: module(),
+ Fun :: atom(),
+ Args :: [term()].
pspawn(M, F, A) ->
gen_server:call({global, pool_master}, {spawn, group_leader(), M, F, A}).
--spec pspawn_link(module(), atom(), [term()]) -> pid().
+-spec pspawn_link(Mod, Fun, Args) -> pid() when
+ Mod :: module(),
+ Fun :: atom(),
+ Args :: [term()].
pspawn_link(M, F, A) ->
P = pspawn(M, F, A),
link(P),
diff --git a/lib/stdlib/src/proc_lib.erl b/lib/stdlib/src/proc_lib.erl
index 4fb64a3353..02bcbb5a60 100644
--- a/lib/stdlib/src/proc_lib.erl
+++ b/lib/stdlib/src/proc_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -40,77 +40,108 @@
-type priority_level() :: 'high' | 'low' | 'max' | 'normal'.
-type spawn_option() :: 'link'
+ | 'monitor'
| {'priority', priority_level()}
| {'min_heap_size', non_neg_integer()}
+ | {'min_bin_vheap_size', non_neg_integer()}
| {'fullsweep_after', non_neg_integer()}.
--type dict_or_pid() :: pid() | [_] | {integer(), integer(), integer()}.
+-type dict_or_pid() :: pid()
+ | (ProcInfo :: [_])
+ | {X :: integer(), Y :: integer(), Z :: integer()}.
%%-----------------------------------------------------------------------------
--spec spawn(function()) -> pid().
+-spec spawn(Fun) -> pid() when
+ Fun :: function().
spawn(F) when is_function(F) ->
Parent = get_my_name(),
Ancestors = get_ancestors(),
erlang:spawn(?MODULE, init_p, [Parent,Ancestors,F]).
--spec spawn(atom(), atom(), [term()]) -> pid().
+-spec spawn(Module, Function, Args) -> pid() when
+ Module :: module(),
+ Function :: atom(),
+ Args :: [term()].
spawn(M,F,A) when is_atom(M), is_atom(F), is_list(A) ->
Parent = get_my_name(),
Ancestors = get_ancestors(),
erlang:spawn(?MODULE, init_p, [Parent,Ancestors,M,F,A]).
--spec spawn_link(function()) -> pid().
+-spec spawn_link(Fun) -> pid() when
+ Fun :: function().
spawn_link(F) when is_function(F) ->
Parent = get_my_name(),
Ancestors = get_ancestors(),
erlang:spawn_link(?MODULE, init_p, [Parent,Ancestors,F]).
--spec spawn_link(atom(), atom(), [term()]) -> pid().
+-spec spawn_link(Module, Function, Args) -> pid() when
+ Module :: module(),
+ Function :: atom(),
+ Args :: [term()].
spawn_link(M,F,A) when is_atom(M), is_atom(F), is_list(A) ->
Parent = get_my_name(),
Ancestors = get_ancestors(),
erlang:spawn_link(?MODULE, init_p, [Parent,Ancestors,M,F,A]).
--spec spawn(node(), function()) -> pid().
+-spec spawn(Node, Fun) -> pid() when
+ Node :: node(),
+ Fun :: function().
spawn(Node, F) when is_function(F) ->
Parent = get_my_name(),
Ancestors = get_ancestors(),
erlang:spawn(Node, ?MODULE, init_p, [Parent,Ancestors,F]).
--spec spawn(node(), atom(), atom(), [term()]) -> pid().
+-spec spawn(Node, Module, Function, Args) -> pid() when
+ Node :: node(),
+ Module :: module(),
+ Function :: atom(),
+ Args :: [term()].
+
spawn(Node, M, F, A) when is_atom(M), is_atom(F), is_list(A) ->
Parent = get_my_name(),
Ancestors = get_ancestors(),
erlang:spawn(Node, ?MODULE, init_p, [Parent,Ancestors,M,F,A]).
--spec spawn_link(node(), function()) -> pid().
+-spec spawn_link(Node, Fun) -> pid() when
+ Node :: node(),
+ Fun :: function().
spawn_link(Node, F) when is_function(F) ->
Parent = get_my_name(),
Ancestors = get_ancestors(),
erlang:spawn_link(Node, ?MODULE, init_p, [Parent,Ancestors,F]).
--spec spawn_link(node(), atom(), atom(), [term()]) -> pid().
+-spec spawn_link(Node, Module, Function, Args) -> pid() when
+ Node :: node(),
+ Module :: module(),
+ Function :: atom(),
+ Args :: [term()].
spawn_link(Node, M, F, A) when is_atom(M), is_atom(F), is_list(A) ->
Parent = get_my_name(),
Ancestors = get_ancestors(),
erlang:spawn_link(Node, ?MODULE, init_p, [Parent,Ancestors,M,F,A]).
--spec spawn_opt(function(), [spawn_option()]) -> pid().
+-spec spawn_opt(Fun, SpawnOpts) -> pid() when
+ Fun :: function(),
+ SpawnOpts :: [spawn_option()].
+
spawn_opt(F, Opts) when is_function(F) ->
Parent = get_my_name(),
Ancestors = get_ancestors(),
check_for_monitor(Opts),
erlang:spawn_opt(?MODULE, init_p, [Parent,Ancestors,F],Opts).
--spec spawn_opt(node(), function(), [spawn_option()]) -> pid().
+-spec spawn_opt(Node, Function, SpawnOpts) -> pid() when
+ Node :: node(),
+ Function :: function(),
+ SpawnOpts :: [spawn_option()].
spawn_opt(Node, F, Opts) when is_function(F) ->
Parent = get_my_name(),
@@ -118,7 +149,11 @@ spawn_opt(Node, F, Opts) when is_function(F) ->
check_for_monitor(Opts),
erlang:spawn_opt(Node, ?MODULE, init_p, [Parent,Ancestors,F], Opts).
--spec spawn_opt(atom(), atom(), [term()], [spawn_option()]) -> pid().
+-spec spawn_opt(Module, Function, Args, SpawnOpts) -> pid() when
+ Module :: module(),
+ Function :: atom(),
+ Args :: [term()],
+ SpawnOpts :: [spawn_option()].
spawn_opt(M, F, A, Opts) when is_atom(M), is_atom(F), is_list(A) ->
Parent = get_my_name(),
@@ -126,7 +161,12 @@ spawn_opt(M, F, A, Opts) when is_atom(M), is_atom(F), is_list(A) ->
check_for_monitor(Opts),
erlang:spawn_opt(?MODULE, init_p, [Parent,Ancestors,M,F,A], Opts).
--spec spawn_opt(node(), atom(), atom(), [term()], [spawn_option()]) -> pid().
+-spec spawn_opt(Node, Module, Function, Args, SpawnOpts) -> pid() when
+ Node :: node(),
+ Module :: module(),
+ Function :: atom(),
+ Args :: [term()],
+ SpawnOpts :: [spawn_option()].
spawn_opt(Node, M, F, A, Opts) when is_atom(M), is_atom(F), is_list(A) ->
Parent = get_my_name(),
@@ -144,7 +184,10 @@ check_for_monitor(SpawnOpts) ->
false
end.
--spec hibernate(module(), atom(), [term()]) -> no_return().
+-spec hibernate(Module, Function, Args) -> no_return() when
+ Module :: module(),
+ Function :: atom(),
+ Args :: [term()].
hibernate(M, F, A) when is_atom(M), is_atom(F), is_list(A) ->
erlang:hibernate(?MODULE, wake_up, [M, F, A]).
@@ -210,35 +253,65 @@ exit_p(Class, Reason) ->
exit(Reason)
end.
--spec start(atom(), atom(), [term()]) -> term().
+-spec start(Module, Function, Args) -> Ret when
+ Module :: module(),
+ Function :: atom(),
+ Args :: [term()],
+ Ret :: term() | {error, Reason :: term()}.
start(M, F, A) when is_atom(M), is_atom(F), is_list(A) ->
start(M, F, A, infinity).
--spec start(atom(), atom(), [term()], timeout()) -> term().
+-spec start(Module, Function, Args, Time) -> Ret when
+ Module :: module(),
+ Function :: atom(),
+ Args :: [term()],
+ Time :: timeout(),
+ Ret :: term() | {error, Reason :: term()}.
start(M, F, A, Timeout) when is_atom(M), is_atom(F), is_list(A) ->
Pid = ?MODULE:spawn(M, F, A),
sync_wait(Pid, Timeout).
--spec start(atom(), atom(), [term()], timeout(), [spawn_option()]) -> term().
+-spec start(Module, Function, Args, Time, SpawnOpts) -> Ret when
+ Module :: module(),
+ Function :: atom(),
+ Args :: [term()],
+ Time :: timeout(),
+ SpawnOpts :: [spawn_option()],
+ Ret :: term() | {error, Reason :: term()}.
start(M, F, A, Timeout, SpawnOpts) when is_atom(M), is_atom(F), is_list(A) ->
Pid = ?MODULE:spawn_opt(M, F, A, SpawnOpts),
sync_wait(Pid, Timeout).
--spec start_link(atom(), atom(), [term()]) -> term().
+-spec start_link(Module, Function, Args) -> Ret when
+ Module :: module(),
+ Function :: atom(),
+ Args :: [term()],
+ Ret :: term() | {error, Reason :: term()}.
start_link(M, F, A) when is_atom(M), is_atom(F), is_list(A) ->
start_link(M, F, A, infinity).
--spec start_link(atom(), atom(), [term()], timeout()) -> term().
+-spec start_link(Module, Function, Args, Time) -> Ret when
+ Module :: module(),
+ Function :: atom(),
+ Args :: [term()],
+ Time :: timeout(),
+ Ret :: term() | {error, Reason :: term()}.
start_link(M, F, A, Timeout) when is_atom(M), is_atom(F), is_list(A) ->
Pid = ?MODULE:spawn_link(M, F, A),
sync_wait(Pid, Timeout).
--spec start_link(atom(),atom(),[term()],timeout(),[spawn_option()]) -> term().
+-spec start_link(Module, Function, Args, Time, SpawnOpts) -> Ret when
+ Module :: module(),
+ Function :: atom(),
+ Args :: [term()],
+ Time :: timeout(),
+ SpawnOpts :: [spawn_option()],
+ Ret :: term() | {error, Reason :: term()}.
start_link(M,F,A,Timeout,SpawnOpts) when is_atom(M), is_atom(F), is_list(A) ->
Pid = ?MODULE:spawn_opt(M, F, A, ensure_link(SpawnOpts)),
@@ -267,13 +340,17 @@ flush(Pid) ->
true
end.
--spec init_ack(pid(), term()) -> 'ok'.
+-spec init_ack(Parent, Ret) -> 'ok' when
+ Parent :: pid(),
+ Ret :: term().
init_ack(Parent, Return) ->
Parent ! {ack, self(), Return},
ok.
--spec init_ack(term()) -> 'ok'.
+-spec init_ack(Ret) -> 'ok' when
+ Ret :: term().
+
init_ack(Return) ->
[Parent|_] = get('$ancestors'),
init_ack(Parent, Return).
@@ -282,7 +359,11 @@ init_ack(Return) ->
%% Fetch the initial call of a proc_lib spawned process.
%% -----------------------------------------------------
--spec initial_call(dict_or_pid()) -> {atom(), atom(), [atom()]} | 'false'.
+-spec initial_call(Process) -> {Module, Function, Args} | 'false' when
+ Process :: dict_or_pid(),
+ Module :: module(),
+ Function :: atom(),
+ Args :: [atom()].
initial_call(DictOrPid) ->
case raw_initial_call(DictOrPid) of
@@ -305,7 +386,11 @@ make_dummy_args(N, Acc) ->
%% This function is typically called from c:i() and c:regs().
%% -----------------------------------------------------
--spec translate_initial_call(dict_or_pid()) -> mfa().
+-spec translate_initial_call(Process) -> {Module, Function, Arity} when
+ Process :: dict_or_pid(),
+ Module :: module(),
+ Function :: atom(),
+ Arity :: byte().
translate_initial_call(DictOrPid) ->
case raw_initial_call(DictOrPid) of
@@ -577,7 +662,8 @@ check(Res) -> Res.
%%% Format (and write) a generated crash info structure.
%%% -----------------------------------------------------------
--spec format([term()]) -> string().
+-spec format(CrashReport) -> string() when
+ CrashReport :: [term()].
format([OwnReport,LinkReport]) ->
OwnFormat = format_report(OwnReport),
diff --git a/lib/stdlib/src/proplists.erl b/lib/stdlib/src/proplists.erl
index 6a45e0f868..68697d0da2 100644
--- a/lib/stdlib/src/proplists.erl
+++ b/lib/stdlib/src/proplists.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -37,7 +37,7 @@
%% overriding the default settings, object properties, annotations,
%% etc.</p>
%%
-%% @type property() = atom() | tuple()
+%% % @type property() = atom() | tuple()
-module(proplists).
@@ -53,14 +53,8 @@
-type property() :: atom() | tuple().
--type aliases() :: [{any(), any()}].
--type negations() :: [{any(), any()}].
--type expansions() :: [{property(), [any()]}].
-
%% ---------------------------------------------------------------------
-%% @spec property(P::property()) -> property()
-%%
%% @doc Creates a normal form (minimal) representation of a property. If
%% <code>P</code> is <code>{Key, true}</code> where <code>Key</code> is
%% an atom, this returns <code>Key</code>, otherwise the whole term
@@ -68,7 +62,8 @@
%%
%% @see property/2
--spec property(property()) -> property().
+-spec property(Property) -> Property when
+ Property :: property().
property({Key, true}) when is_atom(Key) ->
Key;
@@ -76,8 +71,6 @@ property(Property) ->
Property.
-%% @spec property(Key::term(), Value::term()) -> property()
-%%
%% @doc Creates a normal form (minimal) representation of a simple
%% key/value property. Returns <code>Key</code> if <code>Value</code> is
%% <code>true</code> and <code>Key</code> is an atom, otherwise a tuple
@@ -85,7 +78,10 @@ property(Property) ->
%%
%% @see property/1
--spec property(Key::term(), Value::term()) -> atom() | {term(), term()}.
+-spec property(Key, Value) -> Property when
+ Key :: term(),
+ Value :: term(),
+ Property :: atom() | {term(), term()}.
property(Key, true) when is_atom(Key) ->
Key;
@@ -95,14 +91,13 @@ property(Key, Value) ->
%% ---------------------------------------------------------------------
-%% @spec unfold(List::[term()]) -> [term()]
-%%
%% @doc Unfolds all occurences of atoms in <code>List</code> to tuples
%% <code>{Atom, true}</code>.
%%
%% @see compact/1
--spec unfold(List::[term()]) -> [term()].
+-spec unfold(List) -> List when
+ List :: [term()].
unfold([P | Ps]) ->
if is_atom(P) ->
@@ -113,15 +108,14 @@ unfold([P | Ps]) ->
unfold([]) ->
[].
-%% @spec compact(List::[term()]) -> [term()]
-%%
%% @doc Minimizes the representation of all entries in the list. This is
%% equivalent to <code>[property(P) || P &lt;- List]</code>.
%%
%% @see unfold/1
%% @see property/1
--spec compact(List::[property()]) -> [property()].
+-spec compact(List) -> List when
+ List :: [property()].
compact(List) ->
[property(P) || P <- List].
@@ -129,8 +123,6 @@ compact(List) ->
%% ---------------------------------------------------------------------
-%% @spec lookup(Key::term(), List::[term()]) -> none | tuple()
-%%
%% @doc Returns the first entry associated with <code>Key</code> in
%% <code>List</code>, if one exists, otherwise returns
%% <code>none</code>. For an atom <code>A</code> in the list, the tuple
@@ -140,7 +132,9 @@ compact(List) ->
%% @see get_value/2
%% @see get_bool/2
--spec lookup(Key::term(), List::[term()]) -> 'none' | tuple().
+-spec lookup(Key, List) -> 'none' | tuple() when
+ Key :: term(),
+ List :: [term()].
lookup(Key, [P | Ps]) ->
if is_atom(P), P =:= Key ->
@@ -154,15 +148,15 @@ lookup(Key, [P | Ps]) ->
lookup(_Key, []) ->
none.
-%% @spec lookup_all(Key::term(), List::[term()]) -> [tuple()]
-%%
%% @doc Returns the list of all entries associated with <code>Key</code>
%% in <code>List</code>. If no such entry exists, the result is the
%% empty list.
%%
%% @see lookup/2
--spec lookup_all(Key::term(), List::[term()]) -> [tuple()].
+-spec lookup_all(Key, List) -> [tuple()] when
+ Key :: term(),
+ List :: [term()].
lookup_all(Key, [P | Ps]) ->
if is_atom(P), P =:= Key ->
@@ -178,13 +172,13 @@ lookup_all(_Key, []) ->
%% ---------------------------------------------------------------------
-%% @spec is_defined(Key::term(), List::[term()]) -> boolean()
-%%
%% @doc Returns <code>true</code> if <code>List</code> contains at least
%% one entry associated with <code>Key</code>, otherwise
%% <code>false</code> is returned.
--spec is_defined(Key::term(), List::[term()]) -> boolean().
+-spec is_defined(Key, List) -> boolean() when
+ Key :: term(),
+ List :: [term()].
is_defined(Key, [P | Ps]) ->
if is_atom(P), P =:= Key ->
@@ -200,17 +194,15 @@ is_defined(_Key, []) ->
%% ---------------------------------------------------------------------
-%% @spec get_value(Key::term(), List::[term()]) -> term()
%% @equiv get_value(Key, List, undefined)
--spec get_value(Key::term(), List::[term()]) -> term().
+-spec get_value(Key, List) -> term() when
+ Key :: term(),
+ List :: List::[term()].
get_value(Key, List) ->
get_value(Key, List, undefined).
-%% @spec get_value(Key::term(), List::[term()], Default::term()) ->
-%% term()
-%%
%% @doc Returns the value of a simple key/value property in
%% <code>List</code>. If <code>lookup(Key, List)</code> would yield
%% <code>{Key, Value}</code>, this function returns the corresponding
@@ -221,7 +213,10 @@ get_value(Key, List) ->
%% @see get_all_values/2
%% @see get_bool/2
--spec get_value(Key::term(), List::[term()], Default::term()) -> term().
+-spec get_value(Key, List, Default) -> term() when
+ Key :: term(),
+ List :: [term()],
+ Default :: term().
get_value(Key, [P | Ps], Default) ->
if is_atom(P), P =:= Key ->
@@ -240,8 +235,6 @@ get_value(Key, [P | Ps], Default) ->
get_value(_Key, [], Default) ->
Default.
-%% @spec get_all_values(Key, List) -> [term()]
-%%
%% @doc Similar to <code>get_value/2</code>, but returns the list of
%% values for <em>all</em> entries <code>{Key, Value}</code> in
%% <code>List</code>. If no such entry exists, the result is the empty
@@ -249,7 +242,9 @@ get_value(_Key, [], Default) ->
%%
%% @see get_value/2
--spec get_all_values(Key::term(), List::[term()]) -> [term()].
+-spec get_all_values(Key, List) -> [term()] when
+ Key :: term(),
+ List :: [term()].
get_all_values(Key, [P | Ps]) ->
if is_atom(P), P =:= Key ->
@@ -267,8 +262,6 @@ get_all_values(Key, [P | Ps]) ->
get_all_values(_Key, []) ->
[].
-%% @spec append_values(Key::term(), List::[term()]) -> [term()]
-%%
%% @doc Similar to <code>get_all_values/2</code>, but each value is
%% wrapped in a list unless it is already itself a list, and the
%% resulting list of lists is concatenated. This is often useful for
@@ -278,7 +271,9 @@ get_all_values(_Key, []) ->
%%
%% @see get_all_values/2
--spec append_values(Key::term(), List::[term()]) -> [term()].
+-spec append_values(Key, List) -> List when
+ Key :: term(),
+ List :: [term()].
append_values(Key, [P | Ps]) ->
if is_atom(P), P =:= Key ->
@@ -301,8 +296,6 @@ append_values(_Key, []) ->
%% ---------------------------------------------------------------------
-%% @spec get_bool(Key::term(), List::[term()]) -> boolean()
-%%
%% @doc Returns the value of a boolean key/value option. If
%% <code>lookup(Key, List)</code> would yield <code>{Key, true}</code>,
%% this function returns <code>true</code>; otherwise <code>false</code>
@@ -311,7 +304,9 @@ append_values(_Key, []) ->
%% @see lookup/2
%% @see get_value/2
--spec get_bool(Key::term(), List::[term()]) -> boolean().
+-spec get_bool(Key, List) -> boolean() when
+ Key :: term(),
+ List :: [term()].
get_bool(Key, [P | Ps]) ->
if is_atom(P), P =:= Key ->
@@ -333,12 +328,11 @@ get_bool(_Key, []) ->
%% ---------------------------------------------------------------------
-%% @spec get_keys(List::[term()]) -> [term()]
-%%
%% @doc Returns an unordered list of the keys used in <code>List</code>,
%% not containing duplicates.
--spec get_keys(List::[term()]) -> [term()].
+-spec get_keys(List) -> [term()] when
+ List :: [term()].
get_keys(Ps) ->
sets:to_list(get_keys(Ps, sets:new())).
@@ -357,12 +351,12 @@ get_keys([], Keys) ->
%% ---------------------------------------------------------------------
-%% @spec delete(Key::term(), List::[term()]) -> [term()]
-%%
%% @doc Deletes all entries associated with <code>Key</code> from
%% <code>List</code>.
--spec delete(Key::term(), List::[term()]) -> [term()].
+-spec delete(Key, List) -> List when
+ Key :: term(),
+ List::[term()].
delete(Key, [P | Ps]) ->
if is_atom(P), P =:= Key ->
@@ -378,11 +372,6 @@ delete(_, []) ->
%% ---------------------------------------------------------------------
-%% @spec substitute_aliases(Aliases, List::[term()]) -> [term()]
-%%
-%% Aliases = [{Key, Key}]
-%% Key = term()
-%%
%% @doc Substitutes keys of properties. For each entry in
%% <code>List</code>, if it is associated with some key <code>K1</code>
%% such that <code>{K1, K2}</code> occurs in <code>Aliases</code>, the
@@ -398,7 +387,10 @@ delete(_, []) ->
%% @see substitute_negations/2
%% @see normalize/2
--spec substitute_aliases(aliases(), List::[term()]) -> [term()].
+-spec substitute_aliases(Aliases, List) -> List when
+ Aliases :: [{Key, Key}],
+ Key :: term(),
+ List::[term()].
substitute_aliases(As, Props) ->
[substitute_aliases_1(As, P) || P <- Props].
@@ -417,11 +409,6 @@ substitute_aliases_1([], P) ->
%% ---------------------------------------------------------------------
-%% @spec substitute_negations(Negations, List::[term()]) -> [term()]
-%%
-%% Negations = [{Key, Key}]
-%% Key = term()
-%%
%% @doc Substitutes keys of boolean-valued properties and simultaneously
%% negates their values. For each entry in <code>List</code>, if it is
%% associated with some key <code>K1</code> such that <code>{K1,
@@ -443,7 +430,10 @@ substitute_aliases_1([], P) ->
%% @see substitute_aliases/2
%% @see normalize/2
--spec substitute_negations(negations(), List::[term()]) -> [term()].
+-spec substitute_negations(Negations, List) -> List when
+ Negations :: [{Key, Key}],
+ Key :: term(),
+ List :: [term()].
substitute_negations(As, Props) ->
[substitute_negations_1(As, P) || P <- Props].
@@ -472,10 +462,6 @@ substitute_negations_1([], P) ->
%% ---------------------------------------------------------------------
-%% @spec expand(Expansions, List::[term()]) -> [term()]
-%%
-%% Expansions = [{property(), [term()]}]
-%%
%% @doc Expands particular properties to corresponding sets of
%% properties (or other terms). For each pair <code>{Property,
%% Expansion}</code> in <code>Expansions</code>, if <code>E</code> is
@@ -510,7 +496,9 @@ substitute_negations_1([], P) ->
%%
%% @see normalize/2
--spec expand(Expansions::expansions(), [term()]) -> [term()].
+-spec expand(Expansions, List) -> List when
+ Expansions :: [{Property :: property(), Expansion :: [term()]}],
+ List :: [term()].
expand(Es, Ps) when is_list(Ps) ->
Es1 = [{property(P), V} || {P, V} <- Es],
@@ -589,15 +577,6 @@ flatten([]) ->
%% ---------------------------------------------------------------------
-%% @spec normalize(List::[term()], Stages::[Operation]) -> [term()]
-%%
-%% Operation = {aliases, Aliases} | {negations, Negations}
-%% | {expand, Expansions}
-%% Aliases = [{Key, Key}]
-%% Negations = [{Key, Key}]
-%% Key = term()
-%% Expansions = [{property(), [term()]}]
-%%
%% @doc Passes <code>List</code> through a sequence of
%% substitution/expansion stages. For an <code>aliases</code> operation,
%% the function <code>substitute_aliases/2</code> is applied using the
@@ -619,11 +598,15 @@ flatten([]) ->
%% @see expand/2
%% @see compact/1
--type operation() :: {'aliases', aliases()}
- | {'negations', negations()}
- | {'expand', expansions()}.
-
--spec normalize(List::[term()], Stages::[operation()]) -> [term()].
+-spec normalize(List, Stages) -> List when
+ List :: [term()],
+ Stages :: [Operation],
+ Operation :: {'aliases', Aliases}
+ | {'negations', Negations}
+ | {'expand', Expansions},
+ Aliases :: [{Key, Key}],
+ Negations :: [{Key, Key}],
+ Expansions :: [{Property :: property(), Expansion :: [term()]}].
normalize(L, [{aliases, As} | Xs]) ->
normalize(substitute_aliases(As, L), Xs);
@@ -636,10 +619,6 @@ normalize(L, []) ->
%% ---------------------------------------------------------------------
-%% @spec split(List::[term()], Keys::[term()]) -> {Lists, Rest}
-%% Lists = [[term()]]
-%% Rest = [term()]
-%%
%% @doc Partitions <code>List</code> into a list of sublists and a
%% remainder. <code>Lists</code> contains one sublist for each key in
%% <code>Keys</code>, in the corresponding order. The relative order of
@@ -654,7 +633,11 @@ normalize(L, []) ->
%% {[[a], [{b, 5}, b],[{c, 2}, {c, 3, 4}]], [{e, 1}, d]}</pre>
%% </p>
--spec split(List::[term()], Keys::[term()]) -> {[[term()]], [term()]}.
+-spec split(List, Keys) -> {Lists, Rest} when
+ List :: [term()],
+ Keys :: [term()],
+ Lists :: [[term()]],
+ Rest :: [term()].
split(List, Keys) ->
{Store, Rest} = split(List, dict:from_list([{K, []} || K <- Keys]), []),
diff --git a/lib/stdlib/src/qlc.erl b/lib/stdlib/src/qlc.erl
index bc6944e520..5ca04ff023 100644
--- a/lib/stdlib/src/qlc.erl
+++ b/lib/stdlib/src/qlc.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -60,7 +60,7 @@
-record(qlc_table, % qlc:table/2
{trav_fun, % traverse fun
- trav_MS, % bool(); true iff traverse fun takes a match spec
+ trav_MS, % boolean(); true iff traverse fun takes a match spec
pre_fun,
post_fun,
info_fun,
@@ -110,12 +110,12 @@
-record(qlc_cursor, {c}).
-record(qlc_opt,
- {unique = false, % bool()
- cache = false, % bool() | list (true~ets, false~no)
+ {unique = false, % boolean()
+ cache = false, % boolean() | list (true~ets, false~no)
max_lookup = -1, % int() >= 0 | -1 (represents infinity)
join = any, % any | nested_loop | merge | lookup
tmpdir = "", % global tmpdir
- lookup = any, % any | bool()
+ lookup = any, % any | boolean()
max_list = ?MAX_LIST_SIZE, % int() >= 0
tmpdir_usage = allowed % allowed | not_allowed
% | warning_msg | error_msg | info_msg
@@ -125,6 +125,8 @@
-define(THROWN_ERROR, {?MODULE, throw_error, _}).
+-export_type([query_handle/0]).
+
%%% A query handle is a tuple {qlc_handle, Handle} where Handle is one
%%% of #qlc_append, #qlc_table, #qlc_sort, and #qlc_lc.
@@ -144,6 +146,35 @@ get_handle(_) ->
%%% Exported functions
%%%
+-type(query_list_comprehension() :: term()).
+-opaque(query_cursor() :: {qlc_cursor, term()}).
+-opaque(query_handle() :: {qlc_handle, term()}).
+-type(query_handle_or_list() :: query_handle() | list()).
+-type(answers() :: [answer()]).
+-type(answer() :: term()).
+-type(abstract_expr() :: erl_parse:abstract_expr()).
+-type(match_expression() :: ets:match_spec()).
+-type(spawn_options() :: default | [proc_lib:spawn_option()]).
+-type(sort_options() :: [sort_option()] | sort_option()).
+-type(sort_option() :: {compressed, boolean()}
+ | {no_files, no_files()}
+ | {order, order()}
+ | {size, pos_integer()}
+ | {tmpdir, tmp_directory()}
+ | {unique, boolean()}).
+-type(order() :: ascending | descending | order_fun()).
+-type(order_fun() :: fun((term(), term()) -> boolean())).
+-type(tmp_directory() :: [] | file:name()).
+-type(no_files() :: pos_integer()). % > 1
+-type(key_pos() :: pos_integer() | [pos_integer()]).
+-type(max_list_size() :: non_neg_integer()).
+-type(cache() :: ets | list | no).
+-type(tmp_file_usage() :: allowed | not_allowed | info_msg
+ | warning_msg | error_msg).
+
+-spec(append(QHL) -> QH when
+ QHL :: [query_handle_or_list()],
+ QH :: query_handle()).
append(QHs) ->
Hs = [case get_handle(QH) of
badarg -> erlang:error(badarg, [QHs]);
@@ -151,6 +182,10 @@ append(QHs) ->
end || QH <- QHs],
#qlc_handle{h = #qlc_append{hl = Hs}}.
+-spec(append(QH1, QH2) -> QH3 when
+ QH1 :: query_handle_or_list(),
+ QH2 :: query_handle_or_list(),
+ QH3 :: query_handle()).
append(QH1, QH2) ->
Hs = [case get_handle(QH) of
badarg -> erlang:error(badarg, [QH1, QH2]);
@@ -158,9 +193,22 @@ append(QH1, QH2) ->
end || QH <- [QH1, QH2]],
#qlc_handle{h = #qlc_append{hl = Hs}}.
+-spec(cursor(QH) -> Cursor when
+ QH :: query_handle_or_list(),
+ Cursor :: query_cursor()).
cursor(QH) ->
cursor(QH, []).
+-spec(cursor(QH, Options) -> Cursor when
+ QH :: query_handle_or_list(),
+ Options :: [Option] | Option,
+ Option :: {cache_all, cache()} | cache_all
+ | {max_list_size, max_list_size()}
+ | {spawn_options, spawn_options()}
+ | {tmpdir_usage, tmp_file_usage()}
+ | {tmpdir, tmp_directory()}
+ | {unique_all, boolean()} | unique_all,
+ Cursor :: query_cursor()).
cursor(QH, Options) ->
case {options(Options, [unique_all, cache_all, tmpdir,
spawn_options, max_list_size,
@@ -179,6 +227,8 @@ cursor(QH, Options) ->
end
end.
+-spec(delete_cursor(QueryCursor) -> ok when
+ QueryCursor :: query_cursor()).
delete_cursor(#qlc_cursor{c = {_, Owner}}=C) when Owner =/= self() ->
erlang:error(not_cursor_owner, [C]);
delete_cursor(#qlc_cursor{c = {Pid, _}}) ->
@@ -186,15 +236,47 @@ delete_cursor(#qlc_cursor{c = {Pid, _}}) ->
delete_cursor(T) ->
erlang:error(badarg, [T]).
+-spec(e(QH) -> Answers | Error when
+ QH :: query_handle_or_list(),
+ Answers :: answers(),
+ Error :: {error, module(), Reason},
+ Reason :: file_sorter:reason()).
e(QH) ->
eval(QH, []).
+-spec(e(QH, Options) -> Answers | Error when
+ QH :: query_handle_or_list(),
+ Options :: [Option] | Option,
+ Option :: {cache_all, cache()} | cache_all
+ | {max_list_size, max_list_size()}
+ | {tmpdir_usage, tmp_file_usage()}
+ | {tmpdir, tmp_directory()}
+ | {unique_all, boolean()} | unique_all,
+ Answers :: answers(),
+ Error :: {error, module(), Reason},
+ Reason :: file_sorter:reason()).
e(QH, Options) ->
eval(QH, Options).
+-spec(eval(QH) -> Answers | Error when
+ QH :: query_handle_or_list(),
+ Answers :: answers(),
+ Error :: {error, module(), Reason},
+ Reason :: file_sorter:reason()).
eval(QH) ->
eval(QH, []).
+-spec(eval(QH, Options) -> Answers | Error when
+ QH :: query_handle_or_list(),
+ Answers :: answers(),
+ Options :: [Option] | Option,
+ Option :: {cache_all, cache()} | cache_all
+ | {max_list_size, max_list_size()}
+ | {tmpdir_usage, tmp_file_usage()}
+ | {tmpdir, tmp_directory()}
+ | {unique_all, boolean()} | unique_all,
+ Error :: {error, module(), Reason},
+ Reason :: file_sorter:reason()).
eval(QH, Options) ->
case {options(Options, [unique_all, cache_all, tmpdir, max_list_size,
tmpdir_usage]),
@@ -226,9 +308,35 @@ eval(QH, Options) ->
end
end.
+-spec(fold(Function, Acc0, QH) ->
+ Acc1 | Error when
+ QH :: query_handle_or_list(),
+ Function :: fun((answer(), AccIn) -> AccOut),
+ Acc0 :: term(),
+ Acc1 :: term(),
+ AccIn :: term(),
+ AccOut :: term(),
+ Error :: {error, module(), Reason},
+ Reason :: file_sorter:reason()).
fold(Fun, Acc0, QH) ->
fold(Fun, Acc0, QH, []).
+-spec(fold(Function, Acc0, QH, Options) ->
+ Acc1 | Error when
+ QH :: query_handle_or_list(),
+ Function :: fun((answer(), AccIn) -> AccOut),
+ Acc0 :: term(),
+ Acc1 :: term(),
+ AccIn :: term(),
+ AccOut :: term(),
+ Options :: [Option] | Option,
+ Option :: {cache_all, cache()} | cache_all
+ | {max_list_size, max_list_size()}
+ | {tmpdir_usage, tmp_file_usage()}
+ | {tmpdir, tmp_directory()}
+ | {unique_all, boolean()} | unique_all,
+ Error :: {error, module(), Reason},
+ Reason :: file_sorter:reason()).
fold(Fun, Acc0, QH, Options) ->
case {options(Options, [unique_all, cache_all, tmpdir, max_list_size,
tmpdir_usage]),
@@ -258,6 +366,9 @@ fold(Fun, Acc0, QH, Options) ->
end
end.
+-spec(format_error(Error) -> Chars when
+ Error :: {error, module(), term()},
+ Chars :: io_lib:chars()).
format_error(not_a_query_list_comprehension) ->
io_lib:format("argument is not a query list comprehension", []);
format_error({used_generator_variable, V}) ->
@@ -295,9 +406,29 @@ format_error({error, Module, Reason}) ->
format_error(E) ->
io_lib:format("~p~n", [E]).
+-spec(info(QH) -> Info when
+ QH :: query_handle_or_list(),
+ Info :: abstract_expr() | string()).
info(QH) ->
info(QH, []).
+-spec(info(QH, Options) -> Info when
+ QH :: query_handle_or_list(),
+ Options :: [Option] | Option,
+ Option :: EvalOption | ReturnOption,
+ EvalOption :: {cache_all, cache()} | cache_all
+ | {max_list_size, max_list_size()}
+ | {tmpdir_usage, tmp_file_usage()}
+ | {tmpdir, tmp_directory()}
+ | {unique_all, boolean()} | unique_all,
+ ReturnOption :: {depth, Depth}
+ | {flat, boolean()}
+ | {format, Format}
+ | {n_elements, NElements},
+ Depth :: infinity | non_neg_integer(),
+ Format :: abstract_code | string,
+ NElements :: infinity | pos_integer(),
+ Info :: abstract_expr() | string()).
info(QH, Options) ->
case {options(Options, [unique_all, cache_all, flat, format, n_elements,
depth, tmpdir, max_list_size, tmpdir_usage]),
@@ -333,9 +464,18 @@ info(QH, Options) ->
end
end.
+-spec(keysort(KeyPos, QH1) -> QH2 when
+ KeyPos :: key_pos(),
+ QH1 :: query_handle_or_list(),
+ QH2 :: query_handle()).
keysort(KeyPos, QH) ->
keysort(KeyPos, QH, []).
+-spec(keysort(KeyPos, QH1, SortOptions) -> QH2 when
+ KeyPos :: key_pos(),
+ SortOptions :: sort_options(),
+ QH1 :: query_handle_or_list(),
+ QH2 :: query_handle()).
keysort(KeyPos, QH, Options) ->
case {is_keypos(KeyPos),
options(Options, [tmpdir, order, unique, compressed,
@@ -354,9 +494,22 @@ keysort(KeyPos, QH, Options) ->
-define(DEFAULT_NUM_OF_ANSWERS, 10).
+-spec(next_answers(QueryCursor) ->
+ Answers | Error when
+ QueryCursor :: query_cursor(),
+ Answers :: answers(),
+ Error :: {error, module(), Reason},
+ Reason :: file_sorter:reason()).
next_answers(C) ->
next_answers(C, ?DEFAULT_NUM_OF_ANSWERS).
+-spec(next_answers(QueryCursor, NumberOfAnswers) ->
+ Answers | Error when
+ QueryCursor :: query_cursor(),
+ Answers :: answers(),
+ NumberOfAnswers :: all_remaining | pos_integer(),
+ Error :: {error, module(), Reason},
+ Reason :: file_sorter:reason()).
next_answers(#qlc_cursor{c = {_, Owner}}=C,
NumOfAnswers) when Owner =/= self() ->
erlang:error(not_cursor_owner, [C, NumOfAnswers]);
@@ -370,14 +523,35 @@ next_answers(#qlc_cursor{c = {Pid, _}}=C, NumOfAnswers) ->
next_answers(T1, T2) ->
erlang:error(badarg, [T1, T2]).
+-spec(parse_transform(Forms, Options) -> Forms2 when
+ Forms :: [erl_parse:abstract_form()],
+ Forms2 :: [erl_parse:abstract_form()],
+ Options :: [Option],
+ Option :: type_checker | compile:option()).
+
parse_transform(Forms, Options) ->
qlc_pt:parse_transform(Forms, Options).
%% The funcspecs qlc:q/1 and qlc:q/2 are known by erl_eval.erl and
%% erl_lint.erl.
+-spec(q(QLC) -> QH when
+ QLC :: query_list_comprehension(),
+ QH :: query_handle()).
q(QLC_lc) ->
q(QLC_lc, []).
+-spec(q(QLC, Options) -> QH when
+ QH :: query_handle(),
+ Options :: [Option] | Option,
+ Option :: {max_lookup, MaxLookup}
+ | {cache, cache()} | cache
+ | {join, Join}
+ | {lookup, Lookup}
+ | {unique, boolean()} | unique,
+ MaxLookup :: non_neg_integer() | infinity,
+ Join :: any | lookup | merge | nested_loop,
+ Lookup :: boolean() | any,
+ QLC :: query_list_comprehension()).
q(#qlc_lc{}=QLC_lc, Options) ->
case options(Options, [unique, cache, max_lookup, join, lookup]) of
[Unique, Cache, Max, Join, Lookup] ->
@@ -390,9 +564,16 @@ q(#qlc_lc{}=QLC_lc, Options) ->
q(T1, T2) ->
erlang:error(badarg, [T1, T2]).
+-spec(sort(QH1) -> QH2 when
+ QH1 :: query_handle_or_list(),
+ QH2 :: query_handle()).
sort(QH) ->
sort(QH, []).
+-spec(sort(QH1, SortOptions) -> QH2 when
+ SortOptions :: sort_options(),
+ QH1 :: query_handle_or_list(),
+ QH2 :: query_handle()).
sort(QH, Options) ->
case {options(Options, [tmpdir, order, unique, compressed,
size, no_files]), get_handle(QH)} of
@@ -406,14 +587,47 @@ sort(QH, Options) ->
end.
%% Note that the generated code is evaluated by (the slow) erl_eval.
+-spec(string_to_handle(QueryString) -> QH | Error when
+ QueryString :: string(),
+ QH :: query_handle(),
+ Error :: {error, module(), Reason},
+ Reason :: erl_parse:error_info() | erl_scan:error_info()).
string_to_handle(Str) ->
string_to_handle(Str, []).
+-spec(string_to_handle(QueryString, Options) -> QH | Error when
+ QueryString :: string(),
+ Options :: [Option] | Option,
+ Option :: {max_lookup, MaxLookup}
+ | {cache, cache()} | cache
+ | {join, Join}
+ | {lookup, Lookup}
+ | {unique, boolean()} | unique,
+ MaxLookup :: non_neg_integer() | infinity,
+ Join :: any | lookup | merge | nested_loop,
+ Lookup :: boolean() | any,
+ QH :: query_handle(),
+ Error :: {error, module(), Reason},
+ Reason :: erl_parse:error_info() | erl_scan:error_info()).
string_to_handle(Str, Options) ->
- string_to_handle(Str, Options, []).
-
-string_to_handle(Str, Options, Bindings) when is_list(Str),
- is_list(Bindings) ->
+ string_to_handle(Str, Options, erl_eval:new_bindings()).
+
+-spec(string_to_handle(QueryString, Options, Bindings) -> QH | Error when
+ QueryString :: string(),
+ Options :: [Option] | Option,
+ Option :: {max_lookup, MaxLookup}
+ | {cache, cache()} | cache
+ | {join, Join}
+ | {lookup, Lookup}
+ | {unique, boolean()} | unique,
+ MaxLookup :: non_neg_integer() | infinity,
+ Join :: any | lookup | merge | nested_loop,
+ Lookup :: boolean() | any,
+ Bindings :: erl_eval:binding_struct(),
+ QH :: query_handle(),
+ Error :: {error, module(), Reason},
+ Reason :: erl_parse:error_info() | erl_scan:error_info()).
+string_to_handle(Str, Options, Bindings) when is_list(Str) ->
case options(Options, [unique, cache, max_lookup, join, lookup]) of
badarg ->
erlang:error(badarg, [Str, Options, Bindings]);
@@ -447,6 +661,51 @@ string_to_handle(Str, Options, Bindings) when is_list(Str),
string_to_handle(T1, T2, T3) ->
erlang:error(badarg, [T1, T2, T3]).
+-spec(table(TraverseFun, Options) -> QH when
+ TraverseFun :: TraverseFun0 | TraverseFun1,
+ TraverseFun0 :: fun(() -> TraverseResult),
+ TraverseFun1 :: fun((match_expression()) -> TraverseResult),
+ TraverseResult :: Objects | term(),
+ Objects :: [] | [term() | ObjectList],
+ ObjectList :: TraverseFun0 | Objects,
+ Options :: [Option] | Option,
+ Option :: {format_fun, FormatFun}
+ | {info_fun, InfoFun}
+ | {lookup_fun, LookupFun}
+ | {parent_fun, ParentFun}
+ | {post_fun, PostFun}
+ | {pre_fun, PreFun}
+ | {key_equality, KeyComparison},
+ FormatFun :: undefined | fun((SelectedObjects) -> FormatedTable),
+ SelectedObjects :: all
+ | {all, NElements, DepthFun}
+ | {match_spec, match_expression()}
+ | {lookup, Position, Keys}
+ | {lookup, Position, Keys, NElements, DepthFun},
+ NElements :: infinity | pos_integer(),
+ DepthFun :: fun((term()) -> term()),
+ FormatedTable :: {Mod, Fun, Args}
+ | abstract_expr()
+ | string(),
+ InfoFun :: undefined | fun((InfoTag) -> InfoValue),
+ InfoTag :: indices | is_unique_objects | keypos | num_of_objects,
+ InfoValue :: undefined | term(),
+ LookupFun :: undefined | fun((Position, Keys) -> LookupResult),
+ LookupResult :: [term()] | term(),
+ ParentFun :: undefined | fun(() -> ParentFunValue),
+ PostFun :: undefined | fun(() -> term()),
+ PreFun :: undefined | fun((PreArgs) -> term()),
+ PreArgs :: [PreArg],
+ PreArg :: {parent_value, ParentFunValue} | {stop_fun, StopFun},
+ ParentFunValue :: undefined | term(),
+ StopFun :: undefined | fun(() -> term()),
+ KeyComparison :: '=:=' | '==',
+ Position :: pos_integer(),
+ Keys :: [term()],
+ Mod :: atom(),
+ Fun :: atom(),
+ Args :: [term()],
+ QH :: query_handle()).
table(TraverseFun, Options) when is_function(TraverseFun) ->
case {is_function(TraverseFun, 0),
IsFun1 = is_function(TraverseFun, 1)} of
@@ -472,6 +731,11 @@ table(TraverseFun, Options) when is_function(TraverseFun) ->
table(T1, T2) ->
erlang:error(badarg, [T1, T2]).
+-spec(transform_from_evaluator(LC, Bs) -> Expr when
+ LC :: abstract_expr(),
+ Expr :: abstract_expr(),
+ Bs :: erl_eval:binding_struct()).
+
transform_from_evaluator(LC, Bs0) ->
qlc_pt:transform_from_evaluator(LC, Bs0).
@@ -722,8 +986,8 @@ listify(T) ->
%% Optimizations to be carried out.
-record(optz,
- {unique = false, % bool()
- cache = false, % bool() | list
+ {unique = false, % boolean()
+ cache = false, % boolean() | list
join_option = any, % constraint set by the 'join' option
fast_join = no, % no | #qlc_join. 'no' means nested loop.
opt % #qlc_opt
@@ -756,8 +1020,8 @@ listify(T) ->
lu_skip_quals = [], % qualifiers to skip due to lookup
join = {[],[]}, % {Lookup, Merge}
n_objs = undefined, % for join (not used yet)
- is_unique_objects = false, % bool()
- is_cached = false % bool() (true means 'ets' or 'list')
+ is_unique_objects = false, % boolean()
+ is_cached = false % boolean() (true means 'ets' or 'list')
}).
%%% Cursor process functions.
@@ -1143,20 +1407,20 @@ monitor_request(Pid, Req) ->
%% QueryDesc = {qlc, TemplateDesc, [QualDesc], [QueryOpt]}
%% | {table, TableDesc}
%% | {append, [QueryDesc]}
-%% | {sort, QueryDesc, [SortOption]}
-%% | {keysort, KeyPos, QueryDesc, [SortOption]}
+%% | {sort, QueryDesc, [sort_option()]}
+%% | {keysort, key_pos(), QueryDesc, [sort_option()]}
%% | {list, list()}
-%% | {list, QueryDesc, MatchExpression}
+%% | {list, QueryDesc, match_expression()}
%% TableDesc = {Mod, Fun, Args}
-%% | AbstractExpression
-%% | character_list()
+%% | erl_parse:abstract_expr()
+%% | string()
%% Mod = module()
%% Fun = atom()
%% Args = [term()]
%% QualDesc = FilterDesc
%% | {generate, PatternDesc, QueryDesc}
-%% QueryOpt = {cache, bool()} | cache
-%% | {unique, bool()} | unique
+%% QueryOpt = {cache, boolean()} | cache
+%% | {unique, boolean()} | unique
%% FilterDesc = PatternDesc = TemplateDesc = binary()
le_info(#prepared{qh = #simple_qlc{le = LE, p = P, line = L, optz = Optz}},
diff --git a/lib/stdlib/src/qlc_pt.erl b/lib/stdlib/src/qlc_pt.erl
index 24378a0698..21504d707b 100644
--- a/lib/stdlib/src/qlc_pt.erl
+++ b/lib/stdlib/src/qlc_pt.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -63,6 +63,12 @@
%%% Exported functions
%%%
+-spec(parse_transform(Forms, Options) -> Forms2 when
+ Forms :: [erl_parse:abstract_form()],
+ Forms2 :: [erl_parse:abstract_form()],
+ Options :: [Option],
+ Option :: type_checker | compile:option()).
+
parse_transform(Forms, Options) ->
?DEBUG("qlc Parse Transform~n", []),
State = #state{imp = is_qlc_q_imported(Forms),
@@ -96,10 +102,20 @@ parse_transform(Forms, Options) ->
end
end.
+-spec(transform_from_evaluator(LC, Bs) -> Expr when
+ LC :: erl_parse:abstract_expr(),
+ Expr :: erl_parse:abstract_expr(),
+ Bs :: erl_eval:binding_struct()).
+
transform_from_evaluator(LC, Bindings) ->
?DEBUG("qlc Parse Transform (Evaluator Version)~n", []),
transform_expression(LC, Bindings, false).
+-spec(transform_expression(LC, Bs) -> Expr when
+ LC :: erl_parse:abstract_expr(),
+ Expr :: erl_parse:abstract_expr(),
+ Bs :: erl_eval:binding_struct()).
+
transform_expression(LC, Bindings) ->
transform_expression(LC, Bindings, true).
diff --git a/lib/stdlib/src/queue.erl b/lib/stdlib/src/queue.erl
index c09079e8d2..4c6b4d710b 100644
--- a/lib/stdlib/src/queue.erl
+++ b/lib/stdlib/src/queue.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -56,14 +56,16 @@
new() -> {[],[]}. %{RearList,FrontList}
%% O(1)
--spec is_queue(term()) -> boolean().
+-spec is_queue(Term) -> boolean() when
+ Term :: term().
is_queue({R,F}) when is_list(R), is_list(F) ->
true;
is_queue(_) ->
false.
%% O(1)
--spec is_empty(queue()) -> boolean().
+-spec is_empty(Q) -> boolean() when
+ Q :: queue().
is_empty({[],[]}) ->
true;
is_empty({In,Out}) when is_list(In), is_list(Out) ->
@@ -72,14 +74,16 @@ is_empty(Q) ->
erlang:error(badarg, [Q]).
%% O(len(Q))
--spec len(queue()) -> non_neg_integer().
+-spec len(Q) -> non_neg_integer() when
+ Q :: queue().
len({R,F}) when is_list(R), is_list(F) ->
length(R)+length(F);
len(Q) ->
erlang:error(badarg, [Q]).
%% O(len(Q))
--spec to_list(queue()) -> list().
+-spec to_list(Q) -> list() when
+ Q :: queue().
to_list({In,Out}) when is_list(In), is_list(Out) ->
Out++lists:reverse(In, []);
to_list(Q) ->
@@ -88,7 +92,8 @@ to_list(Q) ->
%% Create queue from list
%%
%% O(length(L))
--spec from_list(list()) -> queue().
+-spec from_list(L) -> queue() when
+ L :: list().
from_list(L) when is_list(L) ->
f2r(L);
from_list(L) ->
@@ -97,7 +102,9 @@ from_list(L) ->
%% Return true or false depending on if element is in queue
%%
%% O(length(Q)) worst case
--spec member(term(), queue()) -> boolean().
+-spec member(Item, Q) -> boolean() when
+ Item :: term(),
+ Q :: queue().
member(X, {R,F}) when is_list(R), is_list(F) ->
lists:member(X, R) orelse lists:member(X, F);
member(X, Q) ->
@@ -110,7 +117,10 @@ member(X, Q) ->
%% Put at least one element in each list, if it is cheap
%%
%% O(1)
--spec in(term(), queue()) -> queue().
+-spec in(Item, Q1) -> Q2 when
+ Item :: term(),
+ Q1 :: queue(),
+ Q2 :: queue().
in(X, {[_]=In,[]}) ->
{[X], In};
in(X, {In,Out}) when is_list(In), is_list(Out) ->
@@ -122,7 +132,10 @@ in(X, Q) ->
%% Put at least one element in each list, if it is cheap
%%
%% O(1)
--spec in_r(term(), queue()) -> queue().
+-spec in_r(Item, Q1) -> Q2 when
+ Item :: term(),
+ Q1 :: queue(),
+ Q2 :: queue().
in_r(X, {[],[_]=F}) ->
{F,[X]};
in_r(X, {R,F}) when is_list(R), is_list(F) ->
@@ -133,7 +146,10 @@ in_r(X, Q) ->
%% Take from head/front
%%
%% O(1) amortized, O(len(Q)) worst case
--spec out(queue()) -> {'empty' | {'value',term()}, queue()}.
+-spec out(Q1) -> Result when
+ Q1 :: queue(),
+ Q2 :: queue(),
+ Result :: {{value, Item :: term()}, Q2} | {empty, Q1}.
out({[],[]}=Q) ->
{empty,Q};
out({[V],[]}) ->
@@ -151,7 +167,10 @@ out(Q) ->
%% Take from tail/rear
%%
%% O(1) amortized, O(len(Q)) worst case
--spec out_r(queue()) -> {'empty' | {'value',term()}, queue()}.
+-spec out_r(Q1) -> Result when
+ Q1 :: queue(),
+ Q2 :: queue(),
+ Result :: {{value, Item :: term()}, Q2} | {empty, Q1}.
out_r({[],[]}=Q) ->
{empty,Q};
out_r({[],[V]}) ->
@@ -172,7 +191,9 @@ out_r(Q) ->
%% Return the first element in the queue
%%
%% O(1) since the queue is supposed to be well formed
--spec get(queue()) -> term().
+-spec get(Q) -> Item when
+ Q :: queue(),
+ Item :: term().
get({[],[]}=Q) ->
erlang:error(empty, [Q]);
get({R,F}) when is_list(R), is_list(F) ->
@@ -191,7 +212,9 @@ get([_|R], []) -> % malformed queue -> O(len(Q))
%% Return the last element in the queue
%%
%% O(1) since the queue is supposed to be well formed
--spec get_r(queue()) -> term().
+-spec get_r(Q) -> Item when
+ Q :: queue(),
+ Item :: term().
get_r({[],[]}=Q) ->
erlang:error(empty, [Q]);
get_r({[H|_],F}) when is_list(F) ->
@@ -206,7 +229,9 @@ get_r(Q) ->
%% Return the first element in the queue
%%
%% O(1) since the queue is supposed to be well formed
--spec peek(queue()) -> 'empty' | {'value',term()}.
+-spec peek(Q) -> 'empty' | {'value',Item} when
+ Q :: queue(),
+ Item :: term().
peek({[],[]}) ->
empty;
peek({R,[H|_]}) when is_list(R) ->
@@ -221,7 +246,9 @@ peek(Q) ->
%% Return the last element in the queue
%%
%% O(1) since the queue is supposed to be well formed
--spec peek_r(queue()) -> 'empty' | {'value',term()}.
+-spec peek_r(Q) -> 'empty' | {'value',Item} when
+ Q :: queue(),
+ Item :: term().
peek_r({[],[]}) ->
empty;
peek_r({[H|_],F}) when is_list(F) ->
@@ -236,7 +263,9 @@ peek_r(Q) ->
%% Remove the first element and return resulting queue
%%
%% O(1) amortized
--spec drop(queue()) -> queue().
+-spec drop(Q1) -> Q2 when
+ Q1 :: queue(),
+ Q2 :: queue().
drop({[],[]}=Q) ->
erlang:error(empty, [Q]);
drop({[_],[]}) ->
@@ -254,7 +283,9 @@ drop(Q) ->
%% Remove the last element and return resulting queue
%%
%% O(1) amortized
--spec drop_r(queue()) -> queue().
+-spec drop_r(Q1) -> Q2 when
+ Q1 :: queue(),
+ Q2 :: queue().
drop_r({[],[]}=Q) ->
erlang:error(empty, [Q]);
drop_r({[],[_]}) ->
@@ -275,7 +306,9 @@ drop_r(Q) ->
%% Return reversed queue
%%
%% O(1)
--spec reverse(queue()) -> queue().
+-spec reverse(Q1) -> Q2 when
+ Q1 :: queue(),
+ Q2 :: queue().
reverse({R,F}) when is_list(R), is_list(F) ->
{F,R};
reverse(Q) ->
@@ -285,7 +318,10 @@ reverse(Q) ->
%%
%% Q2 empty: O(1)
%% else: O(len(Q1))
--spec join(queue(), queue()) -> queue().
+-spec join(Q1, Q2) -> Q3 when
+ Q1 :: queue(),
+ Q2 :: queue(),
+ Q3 :: queue().
join({R,F}=Q, {[],[]}) when is_list(R), is_list(F) ->
Q;
join({[],[]}, {R,F}=Q) when is_list(R), is_list(F) ->
@@ -299,7 +335,11 @@ join(Q1, Q2) ->
%%
%% N = 0..len(Q)
%% O(max(N, len(Q)))
--spec split(non_neg_integer(), queue()) -> {queue(),queue()}.
+-spec split(N, Q1) -> {Q2,Q3} when
+ N :: non_neg_integer(),
+ Q1 :: queue(),
+ Q2 :: queue(),
+ Q3 :: queue().
split(0, {R,F}=Q) when is_list(R), is_list(F) ->
{{[],[]},Q};
split(N, {R,F}=Q) when is_integer(N), N >= 1, is_list(R), is_list(F) ->
@@ -340,7 +380,10 @@ split_r1_to_f2(N, [X|R1], F1, R2, F2) ->
%%
%% Fun(_) -> List: O(length(List) * len(Q))
%% else: O(len(Q)
--spec filter(fun((term()) -> boolean() | list()), queue()) -> queue().
+-spec filter(Fun, Q1) -> Q2 when
+ Fun :: fun((Item :: term()) -> boolean() | list()),
+ Q1 :: queue(),
+ Q2 :: queue().
filter(Fun, {R0,F0}) when is_function(Fun, 1), is_list(R0), is_list(F0) ->
F = filter_f(Fun, F0),
R = filter_r(Fun, R0),
@@ -416,7 +459,10 @@ filter_r(Fun, [X|R0]) ->
%% Cons to head
%%
--spec cons(term(), queue()) -> queue().
+-spec cons(Item, Q1) -> Q2 when
+ Item :: term(),
+ Q1 :: queue(),
+ Q2 :: queue().
cons(X, Q) ->
in_r(X, Q).
@@ -425,7 +471,9 @@ cons(X, Q) ->
%% Return the first element in the queue
%%
%% O(1) since the queue is supposed to be well formed
--spec head(queue()) -> term().
+-spec head(Q) -> Item when
+ Q :: queue(),
+ Item :: term().
head({[],[]}=Q) ->
erlang:error(empty, [Q]);
head({R,F}) when is_list(R), is_list(F) ->
@@ -435,7 +483,9 @@ head(Q) ->
%% Remove head element and return resulting queue
%%
--spec tail(queue()) -> queue().
+-spec tail(Q1) -> Q2 when
+ Q1 :: queue(),
+ Q2 :: queue().
tail(Q) ->
drop(Q).
@@ -443,22 +493,35 @@ tail(Q) ->
%% Cons to tail
%%
--spec snoc(queue(), term()) -> queue().
+-spec snoc(Q1, Item) -> Q2 when
+ Q1 :: queue(),
+ Q2 :: queue(),
+ Item :: term().
snoc(Q, X) ->
in(X, Q).
%% Return last element
--spec daeh(queue()) -> term().
+-spec daeh(Q) -> Item when
+ Q :: queue(),
+ Item :: term().
daeh(Q) -> get_r(Q).
--spec last(queue()) -> term().
+-spec last(Q) -> Item when
+ Q :: queue(),
+ Item :: term().
last(Q) -> get_r(Q).
%% Remove last element and return resulting queue
--spec liat(queue()) -> queue().
+-spec liat(Q1) -> Q2 when
+ Q1 :: queue(),
+ Q2 :: queue().
liat(Q) -> drop_r(Q).
--spec lait(queue()) -> queue().
+-spec lait(Q1) -> Q2 when
+ Q1 :: queue(),
+ Q2 :: queue().
lait(Q) -> drop_r(Q). %% Oops, mis-spelled 'tail' reversed. Forget this one.
--spec init(queue()) -> queue().
+-spec init(Q1) -> Q2 when
+ Q1 :: queue(),
+ Q2 :: queue().
init(Q) -> drop_r(Q).
%%--------------------------------------------------------------------------
diff --git a/lib/stdlib/src/random.erl b/lib/stdlib/src/random.erl
index 01227c29b4..dbb524cc74 100644
--- a/lib/stdlib/src/random.erl
+++ b/lib/stdlib/src/random.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -49,7 +49,10 @@ seed() ->
%% seed({A1, A2, A3})
%% Seed random number generation
--spec seed({integer(), integer(), integer()}) -> 'undefined' | ran().
+-spec seed({A1, A2, A3}) -> 'undefined' | ran() when
+ A1 :: integer(),
+ A2 :: integer(),
+ A3 :: integer().
seed({A1, A2, A3}) ->
seed(A1, A2, A3).
@@ -57,7 +60,10 @@ seed({A1, A2, A3}) ->
%% seed(A1, A2, A3)
%% Seed random number generation
--spec seed(integer(), integer(), integer()) -> 'undefined' | ran().
+-spec seed(A1, A2, A3) -> 'undefined' | ran() when
+ A1 :: integer(),
+ A2 :: integer(),
+ A3 :: integer().
seed(A1, A2, A3) ->
put(random_seed,
@@ -93,7 +99,8 @@ uniform() ->
%% Given an integer N >= 1, uniform(N) returns a random integer
%% between 1 and N.
--spec uniform(pos_integer()) -> pos_integer().
+-spec uniform(N) -> pos_integer() when
+ N :: pos_integer().
uniform(N) when is_integer(N), N >= 1 ->
trunc(uniform() * N) + 1.
@@ -104,7 +111,9 @@ uniform(N) when is_integer(N), N >= 1 ->
%% uniform_s(State) -> {F, NewState}
%% Returns a random float between 0 and 1.
--spec uniform_s(ran()) -> {float(), ran()}.
+-spec uniform_s(State0) -> {float(), State1} when
+ State0 :: ran(),
+ State1 :: ran().
uniform_s({A1, A2, A3}) ->
B1 = (A1*171) rem 30269,
@@ -117,7 +126,10 @@ uniform_s({A1, A2, A3}) ->
%% Given an integer N >= 1, uniform(N) returns a random integer
%% between 1 and N.
--spec uniform_s(pos_integer(), ran()) -> {integer(), ran()}.
+-spec uniform_s(N, State0) -> {integer(), State1} when
+ N :: pos_integer(),
+ State0 :: ran(),
+ State1 :: ran().
uniform_s(N, State0) when is_integer(N), N >= 1 ->
{F, State1} = uniform_s(State0),
diff --git a/lib/stdlib/src/re.erl b/lib/stdlib/src/re.erl
index e2cc9f57ce..02dbe60741 100644
--- a/lib/stdlib/src/re.erl
+++ b/lib/stdlib/src/re.erl
@@ -19,15 +19,46 @@
-module(re).
-export([grun/3,urun/3,ucompile/2,replace/3,replace/4,split/2,split/3]).
+%-opaque mp() :: {re_pattern, _, _, _}.
+-type mp() :: {re_pattern, _, _, _}.
+
+-type nl_spec() :: cr | crlf | lf | anycrlf | any.
+
+-type compile_option() :: unicode | anchored | caseless | dollar_endonly
+ | dotall | extended | firstline | multiline
+ | no_auto_capture | dupnames | ungreedy
+ | {newline, nl_spec()}| bsr_anycrlf
+ | bsr_unicode.
+
%% Emulator builtins in this module:
%% re:compile/1
%% re:compile/2
%% re:run/2
%% re:run/3
+-spec split(Subject, RE) -> SplitList when
+ Subject :: iodata() | unicode:charlist(),
+ RE :: mp() | iodata(),
+ SplitList :: [iodata() | unicode:charlist()].
+
split(Subject,RE) ->
split(Subject,RE,[]).
+-spec split(Subject, RE, Options) -> SplitList when
+ Subject :: iodata() | unicode:charlist(),
+ RE :: mp() | iodata(),
+ Options :: [ Option ],
+ Option :: anchored | global | notbol | noteol | notempty
+ | {offset, non_neg_integer()} | {newline, nl_spec()}
+ | bsr_anycrlf | bsr_unicode | {return, ReturnType}
+ | {parts, NumParts} | group | trim | CompileOpt,
+ NumParts :: non_neg_integer() | infinity,
+ ReturnType :: iodata | list | binary,
+ CompileOpt :: compile_option(),
+ SplitList :: [RetData] | [GroupedRetData],
+ GroupedRetData :: [RetData],
+ RetData :: iodata() | unicode:charlist() | binary() | list().
+
split(Subject,RE,Options) ->
try
{NewOpt,Convert,Unicode,Limit,Strip,Group} =
@@ -197,10 +228,26 @@ compile_split(Pat,Options0) when not is_tuple(Pat) ->
compile_split(_,_) ->
throw(badre).
+-spec replace(Subject, RE, Replacement) -> iodata() | unicode:charlist() when
+ Subject :: iodata() | unicode:charlist(),
+ RE :: mp() | iodata(),
+ Replacement :: iodata() | unicode:charlist().
replace(Subject,RE,Replacement) ->
replace(Subject,RE,Replacement,[]).
+-spec replace(Subject, RE, Replacement, Options) -> iodata() | unicode:charlist() when
+ Subject :: iodata() | unicode:charlist(),
+ RE :: mp() | iodata(),
+ Replacement :: iodata() | unicode:charlist(),
+ Options :: [Option],
+ Option :: anchored | global | notbol | noteol | notempty
+ | {offset, non_neg_integer()} | {newline, NLSpec} | bsr_anycrlf
+ | bsr_unicode | {return, ReturnType} | CompileOpt,
+ ReturnType :: iodata | list | binary,
+ CompileOpt :: compile_option(),
+ NLSpec :: cr | crlf | lf | anycrlf | any.
+
replace(Subject,RE,Replacement,Options) ->
try
{NewOpt,Convert,Unicode} =
diff --git a/lib/stdlib/src/regexp.erl b/lib/stdlib/src/regexp.erl
index 8f5994bbee..65f9ca247d 100644
--- a/lib/stdlib/src/regexp.erl
+++ b/lib/stdlib/src/regexp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -37,6 +37,9 @@
-import(string, [substr/2,substr/3]).
-import(lists, [reverse/1]).
+-type errordesc() :: term().
+-opaque regexp() :: term().
+
%% -type matchres() = {match,Start,Length} | nomatch | {error,E}.
%% -type subres() = {ok,RepString,RepCount} | {error,E}.
%% -type splitres() = {ok,[SubString]} | {error,E}.
@@ -287,6 +290,10 @@ re_apply_or(R1, nomatch) -> R1.
%% Convert a sh style regexp into a full AWK one. The main difficulty is
%% getting character sets right as the conventions are different.
+-spec sh_to_awk(ShRegExp) -> AwkRegExp when
+ ShRegExp :: string(),
+ AwkRegExp :: string().
+
sh_to_awk(Sh) -> "^(" ++ sh_to_awk_1(Sh). %Fix the beginning
sh_to_awk_1([$*|Sh]) -> %This matches any string
@@ -336,6 +343,12 @@ special_char(_C) -> false.
%% parse(RegExp) -> {ok,RE} | {error,E}.
%% Parse the regexp described in the string RegExp.
+-spec parse(RegExp) -> ParseRes when
+ RegExp :: string(),
+ ParseRes :: {ok, RE} | {error, Error},
+ RE :: regexp(),
+ Error :: errordesc().
+
parse(S) ->
case catch reg(S) of
{R,[]} -> {ok,R};
@@ -345,6 +358,10 @@ parse(S) ->
%% format_error(Error) -> String.
+-spec format_error(ErrorDescriptor) -> Chars when
+ ErrorDescriptor :: errordesc(),
+ Chars :: io_lib:chars().
+
format_error({illegal,What}) -> ["illegal character `",What,"'"];
format_error({unterminated,What}) -> ["unterminated `",What,"'"];
format_error({char_class,What}) ->
@@ -353,6 +370,14 @@ format_error({char_class,What}) ->
%% -type match(String, RegExp) -> matchres().
%% Find the longest match of RegExp in String.
+-spec match(String, RegExp) -> MatchRes when
+ String :: string(),
+ RegExp :: string() | regexp(),
+ MatchRes :: {match, Start, Length} | nomatch | {error, Error},
+ Start :: pos_integer(),
+ Length :: pos_integer(),
+ Error :: errordesc().
+
match(S, RegExp) when is_list(RegExp) ->
case parse(RegExp) of
{ok,RE} -> match(S, RE);
@@ -378,6 +403,14 @@ match(RE, S, St, Pos, L) ->
%% -type first_match(String, RegExp) -> matchres().
%% Find the first match of RegExp in String.
+-spec first_match(String, RegExp) -> MatchRes when
+ String :: string(),
+ RegExp :: string() | regexp(),
+ MatchRes :: {match, Start, Length} | nomatch | {error, Error},
+ Start :: pos_integer(),
+ Length :: pos_integer(),
+ Error :: errordesc().
+
first_match(S, RegExp) when is_list(RegExp) ->
case parse(RegExp) of
{ok,RE} -> first_match(S, RE);
@@ -400,6 +433,15 @@ first_match(_RE, [], _St) -> nomatch.
%% -type matches(String, RegExp) -> {match,[{Start,Length}]} | {error,E}.
%% Return the all the non-overlapping matches of RegExp in String.
+-spec matches(String, RegExp) -> MatchRes when
+ String :: string(),
+ RegExp :: string() | regexp(),
+ MatchRes :: {match, Matches} | {error, Error},
+ Matches :: [{Start, Length}],
+ Start :: pos_integer(),
+ Length :: pos_integer(),
+ Error :: errordesc().
+
matches(S, RegExp) when is_list(RegExp) ->
case parse(RegExp) of
{ok,RE} -> matches(S, RE);
@@ -420,6 +462,15 @@ matches(S, RE, St) ->
%% the string Replace in String. Accept pre-parsed regular
%% expressions.
+-spec sub(String, RegExp, New) -> SubRes when
+ String :: string(),
+ RegExp :: string() | regexp(),
+ New :: string(),
+ NewString :: string(),
+ SubRes :: {ok, NewString, RepCount} | {error, Error},
+ RepCount :: 0 | 1,
+ Error :: errordesc().
+
sub(String, RegExp, Rep) when is_list(RegExp) ->
case parse(RegExp) of
{ok,RE} -> sub(String, RE, Rep);
@@ -449,6 +500,15 @@ sub_repl([], _M, Rest) -> Rest.
%% Substitute every match of the regular expression RegExp with the
%% string New in String. Accept pre-parsed regular expressions.
+-spec gsub(String, RegExp, New) -> SubRes when
+ String :: string(),
+ RegExp :: string() | regexp(),
+ New :: string(),
+ NewString :: string(),
+ SubRes :: {ok, NewString, RepCount} | {error, Error},
+ RepCount :: non_neg_integer(),
+ Error :: errordesc().
+
gsub(String, RegExp, Rep) when is_list(RegExp) ->
case parse(RegExp) of
{ok,RE} -> gsub(String, RE, Rep);
@@ -462,6 +522,13 @@ gsub(String, RE, Rep) ->
%% Split a string into substrings where the RegExp describes the
%% field seperator. The RegExp " " is specially treated.
+-spec split(String, RegExp) -> SplitRes when
+ String :: string(),
+ RegExp :: string() | regexp(),
+ SplitRes :: {ok, FieldList} | {error, Error},
+ FieldList :: [string()],
+ Error :: errordesc().
+
split(String, " ") -> %This is really special
{ok,RE} = parse("[ \t]+"),
case split_apply(String, RE, true) of
diff --git a/lib/stdlib/src/sets.erl b/lib/stdlib/src/sets.erl
index bcddca2567..3fd6c81e5f 100644
--- a/lib/stdlib/src/sets.erl
+++ b/lib/stdlib/src/sets.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -84,30 +84,38 @@ new() ->
%% is_set(Set) -> boolean().
%% Return 'true' if Set is a set of elements, else 'false'.
--spec is_set(term()) -> boolean().
+-spec is_set(Set) -> boolean() when
+ Set :: term().
is_set(#set{}) -> true;
is_set(_) -> false.
%% size(Set) -> int().
%% Return the number of elements in Set.
--spec size(set()) -> non_neg_integer().
+-spec size(Set) -> non_neg_integer() when
+ Set :: set().
size(S) -> S#set.size.
%% to_list(Set) -> [Elem].
%% Return the elements in Set as a list.
--spec to_list(set()) -> [term()].
+-spec to_list(Set) -> List when
+ Set :: set(),
+ List :: [term()].
to_list(S) ->
fold(fun (Elem, List) -> [Elem|List] end, [], S).
%% from_list([Elem]) -> Set.
%% Build a set from the elements in List.
--spec from_list([term()]) -> set().
+-spec from_list(List) -> Set when
+ List :: [term()],
+ Set :: set().
from_list(L) ->
lists:foldl(fun (E, S) -> add_element(E, S) end, new(), L).
%% is_element(Element, Set) -> boolean().
%% Return 'true' if Element is an element of Set, else 'false'.
--spec is_element(term(), set()) -> boolean().
+-spec is_element(Element, Set) -> boolean() when
+ Element :: term(),
+ Set :: set().
is_element(E, S) ->
Slot = get_slot(S, E),
Bkt = get_bucket(S, Slot),
@@ -115,7 +123,10 @@ is_element(E, S) ->
%% add_element(Element, Set) -> Set.
%% Return Set with Element inserted in it.
--spec add_element(term(), set()) -> set().
+-spec add_element(Element, Set1) -> Set2 when
+ Element :: term(),
+ Set1 :: set(),
+ Set2 :: set().
add_element(E, S0) ->
Slot = get_slot(S0, E),
{S1,Ic} = on_bucket(fun (B0) -> add_bkt_el(E, B0, B0) end, S0, Slot),
@@ -129,7 +140,10 @@ add_bkt_el(E, [], Bkt) -> {[E|Bkt],1}.
%% del_element(Element, Set) -> Set.
%% Return Set but with Element removed.
--spec del_element(term(), set()) -> set().
+-spec del_element(Element, Set1) -> Set2 when
+ Element :: term(),
+ Set1 :: set(),
+ Set2 :: set().
del_element(E, S0) ->
Slot = get_slot(S0, E),
{S1,Dc} = on_bucket(fun (B0) -> del_bkt_el(E, B0) end, S0, Slot),
@@ -144,7 +158,10 @@ del_bkt_el(_, []) -> {[],0}.
%% union(Set1, Set2) -> Set
%% Return the union of Set1 and Set2.
--spec union(set(), set()) -> set().
+-spec union(Set1, Set2) -> Set3 when
+ Set1 :: set(),
+ Set2 :: set(),
+ Set3 :: set().
union(S1, S2) when S1#set.size < S2#set.size ->
fold(fun (E, S) -> add_element(E, S) end, S2, S1);
union(S1, S2) ->
@@ -152,7 +169,9 @@ union(S1, S2) ->
%% union([Set]) -> Set
%% Return the union of the list of sets.
--spec union([set()]) -> set().
+-spec union(SetList) -> Set when
+ SetList :: [set()],
+ Set :: set().
union([S1,S2|Ss]) ->
union1(union(S1, S2), Ss);
union([S]) -> S;
@@ -165,7 +184,10 @@ union1(S1, []) -> S1.
%% intersection(Set1, Set2) -> Set.
%% Return the intersection of Set1 and Set2.
--spec intersection(set(), set()) -> set().
+-spec intersection(Set1, Set2) -> Set3 when
+ Set1 :: set(),
+ Set2 :: set(),
+ Set3 :: set().
intersection(S1, S2) when S1#set.size < S2#set.size ->
filter(fun (E) -> is_element(E, S2) end, S1);
intersection(S1, S2) ->
@@ -173,7 +195,9 @@ intersection(S1, S2) ->
%% intersection([Set]) -> Set.
%% Return the intersection of the list of sets.
--spec intersection([set(),...]) -> set().
+-spec intersection(SetList) -> Set when
+ SetList :: [set(),...],
+ Set :: set().
intersection([S1,S2|Ss]) ->
intersection1(intersection(S1, S2), Ss);
intersection([S]) -> S.
@@ -185,7 +209,9 @@ intersection1(S1, []) -> S1.
%% is_disjoint(Set1, Set2) -> boolean().
%% Check whether Set1 and Set2 are disjoint.
--spec is_disjoint(set(), set()) -> boolean().
+-spec is_disjoint(Set1, Set2) -> boolean() when
+ Set1 :: set(),
+ Set2 :: set().
is_disjoint(S1, S2) when S1#set.size < S2#set.size ->
fold(fun (_, false) -> false;
(E, true) -> not is_element(E, S2)
@@ -198,25 +224,39 @@ is_disjoint(S1, S2) ->
%% subtract(Set1, Set2) -> Set.
%% Return all and only the elements of Set1 which are not also in
%% Set2.
--spec subtract(set(), set()) -> set().
+-spec subtract(Set1, Set2) -> Set3 when
+ Set1 :: set(),
+ Set2 :: set(),
+ Set3 :: set().
subtract(S1, S2) ->
filter(fun (E) -> not is_element(E, S2) end, S1).
%% is_subset(Set1, Set2) -> boolean().
%% Return 'true' when every element of Set1 is also a member of
%% Set2, else 'false'.
--spec is_subset(set(), set()) -> boolean().
+-spec is_subset(Set1, Set2) -> boolean() when
+ Set1 :: set(),
+ Set2 :: set().
is_subset(S1, S2) ->
fold(fun (E, Sub) -> Sub andalso is_element(E, S2) end, true, S1).
%% fold(Fun, Accumulator, Set) -> Accumulator.
%% Fold function Fun over all elements in Set and return Accumulator.
--spec fold(fun((_,_) -> _), T, set()) -> T.
+-spec fold(Function, Acc0, Set) -> Acc1 when
+ Function :: fun((E :: term(),AccIn) -> AccOut),
+ Set :: set(),
+ Acc0 :: T,
+ Acc1 :: T,
+ AccIn :: T,
+ AccOut :: T.
fold(F, Acc, D) -> fold_set(F, Acc, D).
%% filter(Fun, Set) -> Set.
%% Filter Set with Fun.
--spec filter(fun((_) -> boolean()), set()) -> set().
+-spec filter(Pred, Set1) -> Set2 when
+ Pred :: fun((E :: term()) -> boolean()),
+ Set1 :: set(),
+ Set2 :: set().
filter(F, D) -> filter_set(F, D).
%% get_slot(Hashdb, Key) -> Slot.
diff --git a/lib/stdlib/src/shell.erl b/lib/stdlib/src/shell.erl
index ebb221c151..e3e23e09bc 100644
--- a/lib/stdlib/src/shell.erl
+++ b/lib/stdlib/src/shell.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -115,7 +115,9 @@ whereis_evaluator(Shell) ->
%% Call this function to start a user restricted shell
%% from a normal shell session.
--spec start_restricted(module()) -> {'error', code:load_error_rsn()}.
+-spec start_restricted(Module) -> {'error', Reason} when
+ Module :: module(),
+ Reason :: code:load_error_rsn().
start_restricted(RShMod) when is_atom(RShMod) ->
case code:ensure_loaded(RShMod) of
@@ -465,7 +467,7 @@ getc(N) ->
{get({command,N}), get({result,N}), N}.
get_cmd(Num, C) ->
- case catch erl_eval:expr(Num, []) of
+ case catch erl_eval:expr(Num, erl_eval:new_bindings()) of
{value,N,_} when N < 0 -> getc(C+N);
{value,N,_} -> getc(N);
_Other -> {undefined,undefined,undefined}
@@ -1184,6 +1186,8 @@ expr(E, Bs, Lf, Ef) ->
expr_list(Es, Bs, Lf, Ef) ->
erl_eval:expr_list(Es, strip_bindings(Bs), Lf, Ef).
+-spec strip_bindings(erl_eval:binding_struct()) -> erl_eval:binding_struct().
+
strip_bindings(Bs) ->
Bs -- [B || {{module,_},_}=B <- Bs].
@@ -1468,23 +1472,26 @@ set_env(App, Name, Val, Default) ->
application_controller:set_env(App, Name, Val),
Prev.
--spec history(non_neg_integer()) -> non_neg_integer().
+-spec history(N) -> non_neg_integer() when
+ N :: non_neg_integer().
history(L) when is_integer(L), L >= 0 ->
set_env(stdlib, shell_history_length, L, ?DEF_HISTORY).
--spec results(non_neg_integer()) -> non_neg_integer().
+-spec results(N) -> non_neg_integer() when
+ N :: non_neg_integer().
results(L) when is_integer(L), L >= 0 ->
set_env(stdlib, shell_saved_results, L, ?DEF_RESULTS).
--spec catch_exception(boolean()) -> boolean().
+-spec catch_exception(Bool) -> Bool when
+ Bool :: boolean().
catch_exception(Bool) ->
set_env(stdlib, shell_catch_exception, Bool, ?DEF_CATCH_EXCEPTION).
--type prompt_func() :: 'default' | {module(),atom()}.
--spec prompt_func(prompt_func()) -> prompt_func().
+-spec prompt_func(PromptFunc) -> PromptFunc when
+ PromptFunc :: 'default' | {module(),atom()}.
prompt_func(String) ->
set_env(stdlib, shell_prompt_func, String, ?DEF_PROMPT_FUNC).
diff --git a/lib/stdlib/src/slave.erl b/lib/stdlib/src/slave.erl
index 196b659938..d79ee676d9 100644
--- a/lib/stdlib/src/slave.erl
+++ b/lib/stdlib/src/slave.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -54,6 +54,10 @@ pseudo([Master | ServerList]) ->
pseudo(_) ->
error_msg("No master node given to slave:pseudo/1~n",[]).
+-spec pseudo(Master, ServerList) -> ok when
+ Master :: node(),
+ ServerList :: [atom()].
+
pseudo(_, []) -> ok;
pseudo(Master, [S|Tail]) ->
start_pseudo(S, whereis(S), Master),
@@ -68,6 +72,9 @@ start_pseudo(_,_,_) -> ok. %% It's already there
%% This relay can be used to relay all messages directed to a process.
+-spec relay(Pid) -> none() when
+ Pid :: pid().
+
relay({badrpc,Reason}) ->
error_msg(" ** exiting relay server ~w :~w **~n", [self(),Reason]),
exit(Reason);
@@ -120,25 +127,61 @@ relay1(Pid) ->
%% {error, no_rsh} |
%% {error, {already_running, Name@Host}}
+-spec start(Host) -> {ok, Node} | {error, Reason} when
+ Host :: atom(),
+ Node :: node(),
+ Reason :: timeout | no_rsh | {already_running, Node}.
+
start(Host) ->
L = atom_to_list(node()),
Name = upto($@, L),
- start(Host, Name).
+ start(Host, Name, [], no_link).
+
+-spec start(Host, Name) -> {ok, Node} | {error, Reason} when
+ Host :: atom(),
+ Name :: atom(),
+ Node :: node(),
+ Reason :: timeout | no_rsh | {already_running, Node}.
start(Host, Name) ->
start(Host, Name, []).
+-spec start(Host, Name, Args) -> {ok, Node} | {error, Reason} when
+ Host :: atom(),
+ Name :: atom(),
+ Args :: string(),
+ Node :: node(),
+ Reason :: timeout | no_rsh | {already_running, Node}.
+
start(Host, Name, Args) ->
start(Host, Name, Args, no_link).
+-spec start_link(Host) -> {ok, Node} | {error, Reason} when
+ Host :: atom(),
+ Node :: node(),
+ Reason :: timeout | no_rsh | {already_running, Node}.
+
start_link(Host) ->
L = atom_to_list(node()),
Name = upto($@, L),
- start_link(Host, Name).
+ start(Host, Name, [], self()).
+
+-spec start_link(Host, Name) -> {ok, Node} | {error, Reason} when
+ Host :: atom(),
+ Name :: atom(),
+ Node :: node(),
+ Reason :: timeout | no_rsh | {already_running, Node}.
start_link(Host, Name) ->
start_link(Host, Name, []).
+-spec start_link(Host, Name, Args) -> {ok, Node} | {error, Reason} when
+ Host :: atom(),
+ Name :: atom(),
+ Args :: string(),
+ Node :: node(),
+ Reason :: timeout | no_rsh | {already_running, Node}.
+
start_link(Host, Name, Args) ->
start(Host, Name, Args, self()).
@@ -163,6 +206,9 @@ start(Host0, Name, Args, LinkTo, Prog) ->
%% Stops a running node.
+-spec stop(Node) -> ok when
+ Node :: node().
+
stop(Node) ->
% io:format("stop(~p)~n", [Node]),
rpc:call(Node, erlang, halt, []),
diff --git a/lib/stdlib/src/sofs.erl b/lib/stdlib/src/sofs.erl
index a83f803330..d38b8ab37a 100644
--- a/lib/stdlib/src/sofs.erl
+++ b/lib/stdlib/src/sofs.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(sofs).
@@ -40,11 +40,11 @@
substitution/2, projection/2, partition/1, partition/2,
partition/3, multiple_relative_product/2, join/4]).
--export([family_to_relation/1, family_specification/2,
+-export([family_to_relation/1, family_specification/2,
union_of_family/1, intersection_of_family/1,
family_union/1, family_intersection/1,
family_domain/1, family_range/1, family_field/1,
- family_union/2, family_intersection/2, family_difference/2,
+ family_union/2, family_intersection/2, family_difference/2,
partition_family/2, family_projection/2]).
-export([family_to_digraph/1, family_to_digraph/2,
@@ -64,9 +64,9 @@
-compile({inline, [{external_fun,1},{element_type,1}]}).
--compile({inline,
+-compile({inline,
[{unify_types,2}, {match_types,2},
- {test_rel,3}, {symdiff,3},
+ {test_rel,3}, {symdiff,3},
{subst,3}]}).
-compile({inline, [{fam_binop,3}]}).
@@ -80,13 +80,13 @@
-define(TAG, 'Set').
-define(ORDTAG, 'OrdSet').
--record(?TAG, {data = [], type = type}).
--record(?ORDTAG, {orddata = {}, ordtype = type}).
+-record(?TAG, {data = [] :: list(), type = type :: term()}).
+-record(?ORDTAG, {orddata = {} :: tuple(), ordtype = type :: term()}).
-define(LIST(S), (S)#?TAG.data).
-define(TYPE(S), (S)#?TAG.type).
-%%-define(SET(L, T),
-%% case is_type(T) of
+%%-define(SET(L, T),
+%% case is_type(T) of
%% true -> #?TAG{data = L, type = T};
%% false -> erlang:error(badtype, [T])
%% end
@@ -113,14 +113,40 @@
-define(IS_SET_OF(X), is_list(X)).
-define(FAMILY(X, Y), ?BINREL(X, ?SET_OF(Y))).
+-export_type([anyset/0, binary_relation/0, external_set/0, a_function/0,
+ family/0, relation/0, set_of_sets/0, set_fun/0, spec_fun/0,
+ type/0]).
+-export_type([ordset/0, a_set/0]).
+
+-type(anyset() :: ordset() | a_set()).
+-type(binary_relation() :: relation()).
+-type(external_set() :: term()).
+-type(a_function() :: relation()).
+-type(family() :: a_function()).
+-opaque(ordset() :: #?ORDTAG{}).
+-type(relation() :: a_set()).
+-opaque(a_set() :: #?TAG{}).
+-type(set_of_sets() :: a_set()).
+-type(set_fun() :: pos_integer()
+ | {external, fun((external_set()) -> external_set())}
+ | fun((anyset()) -> anyset())).
+-type(spec_fun() :: {external, fun((external_set()) -> boolean())}
+ | fun((anyset()) -> boolean())).
+-type(type() :: term()).
+
+-type(tuple_of(_T) :: tuple()).
+
%%
%% Exported functions
%%
-%%%
+%%%
%%% Create sets
-%%%
+%%%
+-spec(from_term(Term) -> AnySet when
+ AnySet :: anyset(),
+ Term :: term()).
from_term(T) ->
Type = case T of
_ when is_list(T) -> [?ANYTYPE];
@@ -133,6 +159,10 @@ from_term(T) ->
Set
end.
+-spec(from_term(Term, Type) -> AnySet when
+ AnySet :: anyset(),
+ Term :: term(),
+ Type :: type()).
from_term(L, T) ->
case is_type(T) of
true ->
@@ -146,14 +176,23 @@ from_term(L, T) ->
erlang:error(badarg, [L, T])
end.
+-spec(from_external(ExternalSet, Type) -> AnySet when
+ ExternalSet :: external_set(),
+ AnySet :: anyset(),
+ Type :: type()).
from_external(L, ?SET_OF(Type)) ->
?SET(L, Type);
from_external(T, Type) ->
?ORDSET(T, Type).
+-spec(empty_set() -> Set when
+ Set :: a_set()).
empty_set() ->
?SET([], ?ANYTYPE).
+-spec(is_type(Term) -> Bool when
+ Bool :: boolean(),
+ Term :: term()).
is_type(Atom) when ?IS_ATOM_TYPE(Atom), Atom =/= ?ANYTYPE ->
true;
is_type(?SET_OF(T)) ->
@@ -163,19 +202,26 @@ is_type(T) when tuple_size(T) > 0 ->
is_type(_T) ->
false.
+-spec(set(Terms) -> Set when
+ Set :: a_set(),
+ Terms :: [term()]).
set(L) ->
case catch usort(L) of
{'EXIT', _} ->
erlang:error(badarg, [L]);
- SL ->
+ SL ->
?SET(SL, ?ATOM_TYPE)
end.
+-spec(set(Terms, Type) -> Set when
+ Set :: a_set(),
+ Terms :: [term()],
+ Type :: type()).
set(L, ?SET_OF(Type) = T) when ?IS_ATOM_TYPE(Type), Type =/= ?ANYTYPE ->
case catch usort(L) of
{'EXIT', _} ->
erlang:error(badarg, [L, T]);
- SL ->
+ SL ->
?SET(SL, Type)
end;
set(L, ?SET_OF(_) = T) ->
@@ -188,6 +234,12 @@ set(L, ?SET_OF(_) = T) ->
set(L, T) ->
erlang:error(badarg, [L, T]).
+-spec(from_sets(ListOfSets) -> Set when
+ Set :: a_set(),
+ ListOfSets :: [anyset()];
+ (TupleOfSets) -> Ordset when
+ Ordset :: ordset(),
+ TupleOfSets :: tuple_of(anyset())).
from_sets(Ss) when is_list(Ss) ->
case set_of_sets(Ss, [], ?ANYTYPE) of
{error, Error} ->
@@ -205,6 +257,9 @@ from_sets(Tuple) when is_tuple(Tuple) ->
from_sets(T) ->
erlang:error(badarg, [T]).
+-spec(relation(Tuples) -> Relation when
+ Relation :: relation(),
+ Tuples :: [tuple()]).
relation([]) ->
?SET([], ?BINREL(?ATOM_TYPE, ?ATOM_TYPE));
relation(Ts = [T | _]) when is_tuple(T) ->
@@ -217,6 +272,11 @@ relation(Ts = [T | _]) when is_tuple(T) ->
relation(E) ->
erlang:error(badarg, [E]).
+-spec(relation(Tuples, Type) -> Relation when
+ N :: integer(),
+ Type :: N | type(),
+ Relation :: relation(),
+ Tuples :: [tuple()]).
relation(Ts, TS) ->
case catch rel(Ts, TS) of
{'EXIT', _} ->
@@ -225,6 +285,9 @@ relation(Ts, TS) ->
Set
end.
+-spec(a_function(Tuples) -> Function when
+ Function :: a_function(),
+ Tuples :: [tuple()]).
a_function(Ts) ->
case catch func(Ts, ?BINREL(?ATOM_TYPE, ?ATOM_TYPE)) of
{'EXIT', _} ->
@@ -235,6 +298,10 @@ a_function(Ts) ->
Set
end.
+-spec(a_function(Tuples, Type) -> Function when
+ Function :: a_function(),
+ Tuples :: [tuple()],
+ Type :: type()).
a_function(Ts, T) ->
case catch a_func(Ts, T) of
{'EXIT', _} ->
@@ -245,6 +312,9 @@ a_function(Ts, T) ->
Set
end.
+-spec(family(Tuples) -> Family when
+ Family :: family(),
+ Tuples :: [tuple()]).
family(Ts) ->
case catch fam2(Ts, ?FAMILY(?ATOM_TYPE, ?ATOM_TYPE)) of
{'EXIT', _} ->
@@ -255,6 +325,10 @@ family(Ts) ->
Set
end.
+-spec(family(Tuples, Type) -> Family when
+ Family :: family(),
+ Tuples :: [tuple()],
+ Type :: type()).
family(Ts, T) ->
case catch fam(Ts, T) of
{'EXIT', _} ->
@@ -265,20 +339,30 @@ family(Ts, T) ->
Set
end.
-%%%
+%%%
%%% Functions on sets.
-%%%
+%%%
+-spec(to_external(AnySet) -> ExternalSet when
+ ExternalSet :: external_set(),
+ AnySet :: anyset()).
to_external(S) when ?IS_SET(S) ->
?LIST(S);
to_external(S) when ?IS_ORDSET(S) ->
?ORDDATA(S).
+-spec(type(AnySet) -> Type when
+ AnySet :: anyset(),
+ Type :: type()).
type(S) when ?IS_SET(S) ->
?SET_OF(?TYPE(S));
type(S) when ?IS_ORDSET(S) ->
?ORDTYPE(S).
+-spec(to_sets(ASet) -> Sets when
+ ASet :: a_set() | ordset(),
+ Sets :: tuple_of(AnySet) | [AnySet],
+ AnySet :: anyset()).
to_sets(S) when ?IS_SET(S) ->
case ?TYPE(S) of
?SET_OF(Type) -> list_of_sets(?LIST(S), Type, []);
@@ -289,6 +373,9 @@ to_sets(S) when ?IS_ORDSET(S), is_tuple(?ORDTYPE(S)) ->
to_sets(S) when ?IS_ORDSET(S) ->
erlang:error(badarg, [S]).
+-spec(no_elements(ASet) -> NoElements when
+ ASet :: a_set() | ordset(),
+ NoElements :: pos_integer()).
no_elements(S) when ?IS_SET(S) ->
length(?LIST(S));
no_elements(S) when ?IS_ORDSET(S), is_tuple(?ORDTYPE(S)) ->
@@ -296,6 +383,10 @@ no_elements(S) when ?IS_ORDSET(S), is_tuple(?ORDTYPE(S)) ->
no_elements(S) when ?IS_ORDSET(S) ->
erlang:error(badarg, [S]).
+-spec(specification(Fun, Set1) -> Set2 when
+ Fun :: spec_fun(),
+ Set1 :: a_set(),
+ Set2 :: a_set()).
specification(Fun, S) when ?IS_SET(S) ->
Type = ?TYPE(S),
R = case external_fun(Fun) of
@@ -311,36 +402,62 @@ specification(Fun, S) when ?IS_SET(S) ->
erlang:error(Bad, [Fun, S])
end.
+-spec(union(Set1, Set2) -> Set3 when
+ Set1 :: a_set(),
+ Set2 :: a_set(),
+ Set3 :: a_set()).
union(S1, S2) when ?IS_SET(S1), ?IS_SET(S2) ->
case unify_types(?TYPE(S1), ?TYPE(S2)) of
[] -> erlang:error(type_mismatch, [S1, S2]);
Type -> ?SET(umerge(?LIST(S1), ?LIST(S2)), Type)
end.
+-spec(intersection(Set1, Set2) -> Set3 when
+ Set1 :: a_set(),
+ Set2 :: a_set(),
+ Set3 :: a_set()).
intersection(S1, S2) when ?IS_SET(S1), ?IS_SET(S2) ->
case unify_types(?TYPE(S1), ?TYPE(S2)) of
[] -> erlang:error(type_mismatch, [S1, S2]);
Type -> ?SET(intersection(?LIST(S1), ?LIST(S2), []), Type)
end.
+-spec(difference(Set1, Set2) -> Set3 when
+ Set1 :: a_set(),
+ Set2 :: a_set(),
+ Set3 :: a_set()).
difference(S1, S2) when ?IS_SET(S1), ?IS_SET(S2) ->
case unify_types(?TYPE(S1), ?TYPE(S2)) of
[] -> erlang:error(type_mismatch, [S1, S2]);
Type -> ?SET(difference(?LIST(S1), ?LIST(S2), []), Type)
end.
+-spec(symdiff(Set1, Set2) -> Set3 when
+ Set1 :: a_set(),
+ Set2 :: a_set(),
+ Set3 :: a_set()).
symdiff(S1, S2) when ?IS_SET(S1), ?IS_SET(S2) ->
case unify_types(?TYPE(S1), ?TYPE(S2)) of
[] -> erlang:error(type_mismatch, [S1, S2]);
Type -> ?SET(symdiff(?LIST(S1), ?LIST(S2), []), Type)
end.
+-spec(symmetric_partition(Set1, Set2) -> {Set3, Set4, Set5} when
+ Set1 :: a_set(),
+ Set2 :: a_set(),
+ Set3 :: a_set(),
+ Set4 :: a_set(),
+ Set5 :: a_set()).
symmetric_partition(S1, S2) when ?IS_SET(S1), ?IS_SET(S2) ->
case unify_types(?TYPE(S1), ?TYPE(S2)) of
[] -> erlang:error(type_mismatch, [S1, S2]);
Type -> sympart(?LIST(S1), ?LIST(S2), [], [], [], Type)
end.
+-spec(product(Set1, Set2) -> BinRel when
+ BinRel :: binary_relation(),
+ Set1 :: a_set(),
+ Set2 :: a_set()).
product(S1, S2) when ?IS_SET(S1), ?IS_SET(S2) ->
if
?TYPE(S1) =:= ?ANYTYPE -> S1;
@@ -351,6 +468,9 @@ product(S1, S2) when ?IS_SET(S1), ?IS_SET(S2) ->
?SET(relprod(map(F, ?LIST(S1)), map(F, ?LIST(S2))), T)
end.
+-spec(product(TupleOfSets) -> Relation when
+ Relation :: relation(),
+ TupleOfSets :: tuple_of(a_set())).
product({S1, S2}) ->
product(S1, S2);
product(T) when is_tuple(T) ->
@@ -365,11 +485,15 @@ product(T) when is_tuple(T) ->
case member([], L) of
true ->
empty_set();
- false ->
+ false ->
?SET(reverse(prod(L, [], [])), Type)
end
end.
+-spec(constant_function(Set, AnySet) -> Function when
+ AnySet :: anyset(),
+ Function :: a_function(),
+ Set :: a_set()).
constant_function(S, E) when ?IS_SET(S) ->
case {?TYPE(S), is_sofs_set(E)} of
{?ANYTYPE, true} -> S;
@@ -381,6 +505,10 @@ constant_function(S, E) when ?IS_SET(S) ->
constant_function(S, E) when ?IS_ORDSET(S) ->
erlang:error(badarg, [S, E]).
+-spec(is_equal(AnySet1, AnySet2) -> Bool when
+ AnySet1 :: anyset(),
+ AnySet2 :: anyset(),
+ Bool :: boolean()).
is_equal(S1, S2) when ?IS_SET(S1), ?IS_SET(S2) ->
case match_types(?TYPE(S1), ?TYPE(S2)) of
true -> ?LIST(S1) == ?LIST(S2);
@@ -396,12 +524,19 @@ is_equal(S1, S2) when ?IS_SET(S1), ?IS_ORDSET(S2) ->
is_equal(S1, S2) when ?IS_ORDSET(S1), ?IS_SET(S2) ->
erlang:error(type_mismatch, [S1, S2]).
+-spec(is_subset(Set1, Set2) -> Bool when
+ Bool :: boolean(),
+ Set1 :: a_set(),
+ Set2 :: a_set()).
is_subset(S1, S2) when ?IS_SET(S1), ?IS_SET(S2) ->
case match_types(?TYPE(S1), ?TYPE(S2)) of
true -> subset(?LIST(S1), ?LIST(S2));
false -> erlang:error(type_mismatch, [S1, S2])
end.
+-spec(is_sofs_set(Term) -> Bool when
+ Bool :: boolean(),
+ Term :: term()).
is_sofs_set(S) when ?IS_SET(S) ->
true;
is_sofs_set(S) when ?IS_ORDSET(S) ->
@@ -409,16 +544,26 @@ is_sofs_set(S) when ?IS_ORDSET(S) ->
is_sofs_set(_S) ->
false.
+-spec(is_set(AnySet) -> Bool when
+ AnySet :: anyset(),
+ Bool :: boolean()).
is_set(S) when ?IS_SET(S) ->
true;
is_set(S) when ?IS_ORDSET(S) ->
false.
-is_empty_set(S) when ?IS_SET(S) ->
+-spec(is_empty_set(AnySet) -> Bool when
+ AnySet :: anyset(),
+ Bool :: boolean()).
+is_empty_set(S) when ?IS_SET(S) ->
?LIST(S) =:= [];
is_empty_set(S) when ?IS_ORDSET(S) ->
false.
+-spec(is_disjoint(Set1, Set2) -> Bool when
+ Bool :: boolean(),
+ Set1 :: a_set(),
+ Set2 :: a_set()).
is_disjoint(S1, S2) when ?IS_SET(S1), ?IS_SET(S2) ->
case match_types(?TYPE(S1), ?TYPE(S2)) of
true ->
@@ -433,6 +578,9 @@ is_disjoint(S1, S2) when ?IS_SET(S1), ?IS_SET(S2) ->
%%% Functions on set-of-sets.
%%%
+-spec(union(SetOfSets) -> Set when
+ Set :: a_set(),
+ SetOfSets :: set_of_sets()).
union(Sets) when ?IS_SET(Sets) ->
case ?TYPE(Sets) of
?SET_OF(Type) -> ?SET(lunion(?LIST(Sets)), Type);
@@ -440,6 +588,9 @@ union(Sets) when ?IS_SET(Sets) ->
_ -> erlang:error(badarg, [Sets])
end.
+-spec(intersection(SetOfSets) -> Set when
+ Set :: a_set(),
+ SetOfSets :: set_of_sets()).
intersection(Sets) when ?IS_SET(Sets) ->
case ?LIST(Sets) of
[] -> erlang:error(badarg, [Sets]);
@@ -451,32 +602,41 @@ intersection(Sets) when ?IS_SET(Sets) ->
end
end.
+-spec(canonical_relation(SetOfSets) -> BinRel when
+ BinRel :: binary_relation(),
+ SetOfSets :: set_of_sets()).
canonical_relation(Sets) when ?IS_SET(Sets) ->
ST = ?TYPE(Sets),
case ST of
?SET_OF(?ANYTYPE) -> empty_set();
- ?SET_OF(Type) ->
+ ?SET_OF(Type) ->
?SET(can_rel(?LIST(Sets), []), ?BINREL(Type, ST));
?ANYTYPE -> Sets;
_ -> erlang:error(badarg, [Sets])
end.
-%%%
+%%%
%%% Functions on binary relations only.
-%%%
+%%%
rel2fam(R) ->
relation_to_family(R).
+-spec(relation_to_family(BinRel) -> Family when
+ Family :: family(),
+ BinRel :: binary_relation()).
%% Inlined.
relation_to_family(R) when ?IS_SET(R) ->
case ?TYPE(R) of
- ?BINREL(DT, RT) ->
+ ?BINREL(DT, RT) ->
?SET(rel2family(?LIST(R)), ?FAMILY(DT, RT));
?ANYTYPE -> R;
_Else -> erlang:error(badarg, [R])
end.
+-spec(domain(BinRel) -> Set when
+ BinRel :: binary_relation(),
+ Set :: a_set()).
domain(R) when ?IS_SET(R) ->
case ?TYPE(R) of
?BINREL(DT, _) -> ?SET(dom(?LIST(R)), DT);
@@ -484,6 +644,9 @@ domain(R) when ?IS_SET(R) ->
_Else -> erlang:error(badarg, [R])
end.
+-spec(range(BinRel) -> Set when
+ BinRel :: binary_relation(),
+ Set :: a_set()).
range(R) when ?IS_SET(R) ->
case ?TYPE(R) of
?BINREL(_, RT) -> ?SET(ran(?LIST(R), []), RT);
@@ -491,35 +654,63 @@ range(R) when ?IS_SET(R) ->
_ -> erlang:error(badarg, [R])
end.
+-spec(field(BinRel) -> Set when
+ BinRel :: binary_relation(),
+ Set :: a_set()).
%% In "Introduction to LOGIC", Suppes defines the field of a binary
%% relation to be the union of the domain and the range (or
%% counterdomain).
field(R) ->
union(domain(R), range(R)).
+-spec(relative_product(ListOfBinRels) -> BinRel2 when
+ ListOfBinRels :: [BinRel, ...],
+ BinRel :: binary_relation(),
+ BinRel2 :: binary_relation()).
+%% The following clause is kept for backward compatibility.
+%% The list is due to Dialyzer's specs.
relative_product(RT) when is_tuple(RT) ->
- case relprod_n(RT, foo, false, false) of
- {error, Reason} ->
- erlang:error(Reason, [RT]);
+ relative_product(tuple_to_list(RT));
+relative_product(RL) when is_list(RL) ->
+ case relprod_n(RL, foo, false, false) of
+ {error, Reason} ->
+ erlang:error(Reason, [RL]);
Reply ->
Reply
end.
+-spec(relative_product(ListOfBinRels, BinRel1) -> BinRel2 when
+ ListOfBinRels :: [BinRel, ...],
+ BinRel :: binary_relation(),
+ BinRel1 :: binary_relation(),
+ BinRel2 :: binary_relation();
+ (BinRel1, BinRel2) -> BinRel3 when
+ BinRel1 :: binary_relation(),
+ BinRel2 :: binary_relation(),
+ BinRel3 :: binary_relation()).
relative_product(R1, R2) when ?IS_SET(R1), ?IS_SET(R2) ->
relative_product1(converse(R1), R2);
+%% The following clause is kept for backward compatibility.
+%% The list is due to Dialyzer's specs.
relative_product(RT, R) when is_tuple(RT), ?IS_SET(R) ->
+ relative_product(tuple_to_list(RT), R);
+relative_product(RL, R) when is_list(RL), ?IS_SET(R) ->
EmptyR = case ?TYPE(R) of
?BINREL(_, _) -> ?LIST(R) =:= [];
?ANYTYPE -> true;
- _ -> erlang:error(badarg, [RT, R])
+ _ -> erlang:error(badarg, [RL, R])
end,
- case relprod_n(RT, R, EmptyR, true) of
- {error, Reason} ->
- erlang:error(Reason, [RT, R]);
+ case relprod_n(RL, R, EmptyR, true) of
+ {error, Reason} ->
+ erlang:error(Reason, [RL, R]);
Reply ->
Reply
end.
+-spec(relative_product1(BinRel1, BinRel2) -> BinRel3 when
+ BinRel1 :: binary_relation(),
+ BinRel2 :: binary_relation(),
+ BinRel3 :: binary_relation()).
relative_product1(R1, R2) when ?IS_SET(R1), ?IS_SET(R2) ->
{DTR1, RTR1} = case ?TYPE(R1) of
?BINREL(_, _) = R1T -> R1T;
@@ -538,16 +729,23 @@ relative_product1(R1, R2) when ?IS_SET(R1), ?IS_SET(R2) ->
false -> erlang:error(type_mismatch, [R1, R2])
end.
+-spec(converse(BinRel1) -> BinRel2 when
+ BinRel1 :: binary_relation(),
+ BinRel2 :: binary_relation()).
converse(R) when ?IS_SET(R) ->
case ?TYPE(R) of
?BINREL(DT, RT) -> ?SET(converse(?LIST(R), []), ?BINREL(RT, DT));
?ANYTYPE -> R;
_ -> erlang:error(badarg, [R])
end.
-
+
+-spec(image(BinRel, Set1) -> Set2 when
+ BinRel :: binary_relation(),
+ Set1 :: a_set(),
+ Set2 :: a_set()).
image(R, S) when ?IS_SET(R), ?IS_SET(S) ->
case ?TYPE(R) of
- ?BINREL(DT, RT) ->
+ ?BINREL(DT, RT) ->
case match_types(DT, ?TYPE(S)) of
true ->
?SET(usort(restrict(?LIST(S), ?LIST(R))), RT);
@@ -558,9 +756,13 @@ image(R, S) when ?IS_SET(R), ?IS_SET(S) ->
_ -> erlang:error(badarg, [R, S])
end.
+-spec(inverse_image(BinRel, Set1) -> Set2 when
+ BinRel :: binary_relation(),
+ Set1 :: a_set(),
+ Set2 :: a_set()).
inverse_image(R, S) when ?IS_SET(R), ?IS_SET(S) ->
case ?TYPE(R) of
- ?BINREL(DT, RT) ->
+ ?BINREL(DT, RT) ->
case match_types(RT, ?TYPE(S)) of
true ->
NL = restrict(?LIST(S), converse(?LIST(R), [])),
@@ -572,17 +774,23 @@ inverse_image(R, S) when ?IS_SET(R), ?IS_SET(S) ->
_ -> erlang:error(badarg, [R, S])
end.
+-spec(strict_relation(BinRel1) -> BinRel2 when
+ BinRel1 :: binary_relation(),
+ BinRel2 :: binary_relation()).
strict_relation(R) when ?IS_SET(R) ->
case ?TYPE(R) of
- Type = ?BINREL(_, _) ->
+ Type = ?BINREL(_, _) ->
?SET(strict(?LIST(R), []), Type);
?ANYTYPE -> R;
_ -> erlang:error(badarg, [R])
end.
-
+
+-spec(weak_relation(BinRel1) -> BinRel2 when
+ BinRel1 :: binary_relation(),
+ BinRel2 :: binary_relation()).
weak_relation(R) when ?IS_SET(R) ->
case ?TYPE(R) of
- ?BINREL(DT, RT) ->
+ ?BINREL(DT, RT) ->
case unify_types(DT, RT) of
[] ->
erlang:error(badarg, [R]);
@@ -592,7 +800,12 @@ weak_relation(R) when ?IS_SET(R) ->
?ANYTYPE -> R;
_ -> erlang:error(badarg, [R])
end.
-
+
+-spec(extension(BinRel1, Set, AnySet) -> BinRel2 when
+ AnySet :: anyset(),
+ BinRel1 :: binary_relation(),
+ BinRel2 :: binary_relation(),
+ Set :: a_set()).
extension(R, S, E) when ?IS_SET(R), ?IS_SET(S) ->
case {?TYPE(R), ?TYPE(S), is_sofs_set(E)} of
{T=?BINREL(DT, RT), ST, true} ->
@@ -621,9 +834,12 @@ extension(R, S, E) when ?IS_SET(R), ?IS_SET(S) ->
erlang:error(badarg, [R, S, E])
end.
+-spec(is_a_function(BinRel) -> Bool when
+ Bool :: boolean(),
+ BinRel :: binary_relation()).
is_a_function(R) when ?IS_SET(R) ->
case ?TYPE(R) of
- ?BINREL(_, _) ->
+ ?BINREL(_, _) ->
case ?LIST(R) of
[] -> true;
[{V,_} | Es] -> is_a_func(Es, V)
@@ -632,16 +848,28 @@ is_a_function(R) when ?IS_SET(R) ->
_ -> erlang:error(badarg, [R])
end.
+-spec(restriction(BinRel1, Set) -> BinRel2 when
+ BinRel1 :: binary_relation(),
+ BinRel2 :: binary_relation(),
+ Set :: a_set()).
restriction(Relation, Set) ->
restriction(1, Relation, Set).
+-spec(drestriction(BinRel1, Set) -> BinRel2 when
+ BinRel1 :: binary_relation(),
+ BinRel2 :: binary_relation(),
+ Set :: a_set()).
drestriction(Relation, Set) ->
drestriction(1, Relation, Set).
-%%%
+%%%
%%% Functions on functions only.
-%%%
+%%%
+-spec(composite(Function1, Function2) -> Function3 when
+ Function1 :: a_function(),
+ Function2 :: a_function(),
+ Function3 :: a_function()).
composite(Fn1, Fn2) when ?IS_SET(Fn1), ?IS_SET(Fn2) ->
?BINREL(DTF1, RTF1) = case ?TYPE(Fn1)of
?BINREL(_, _) = F1T -> F1T;
@@ -656,7 +884,7 @@ composite(Fn1, Fn2) when ?IS_SET(Fn1), ?IS_SET(Fn2) ->
case match_types(RTF1, DTF2) of
true when DTF1 =:= ?ANYTYPE -> Fn1;
true when DTF2 =:= ?ANYTYPE -> Fn2;
- true ->
+ true ->
case comp(?LIST(Fn1), ?LIST(Fn2)) of
SL when is_list(SL) ->
?SET(sort(SL), ?BINREL(DTF1, RTF2));
@@ -666,9 +894,12 @@ composite(Fn1, Fn2) when ?IS_SET(Fn1), ?IS_SET(Fn2) ->
false -> erlang:error(type_mismatch, [Fn1, Fn2])
end.
+-spec(inverse(Function1) -> Function2 when
+ Function1 :: a_function(),
+ Function2 :: a_function()).
inverse(Fn) when ?IS_SET(Fn) ->
case ?TYPE(Fn) of
- ?BINREL(DT, RT) ->
+ ?BINREL(DT, RT) ->
case inverse1(?LIST(Fn)) of
SL when is_list(SL) ->
?SET(SL, ?BINREL(RT, DT));
@@ -678,11 +909,16 @@ inverse(Fn) when ?IS_SET(Fn) ->
?ANYTYPE -> Fn;
_ -> erlang:error(badarg, [Fn])
end.
-
-%%%
+
+%%%
%%% Functions on relations (binary or other).
-%%%
+%%%
+-spec(restriction(SetFun, Set1, Set2) -> Set3 when
+ SetFun :: set_fun(),
+ Set1 :: a_set(),
+ Set2 :: a_set(),
+ Set3 :: a_set()).
%% Equivalent to range(restriction(inverse(substitution(Fun, S1)), S2)).
restriction(I, R, S) when is_integer(I), ?IS_SET(R), ?IS_SET(S) ->
RT = ?TYPE(R),
@@ -747,6 +983,11 @@ restriction(SetFun, S1, S2) when ?IS_SET(S1), ?IS_SET(S2) ->
end
end.
+-spec(drestriction(SetFun, Set1, Set2) -> Set3 when
+ SetFun :: set_fun(),
+ Set1 :: a_set(),
+ Set2 :: a_set(),
+ Set3 :: a_set()).
drestriction(I, R, S) when is_integer(I), ?IS_SET(R), ?IS_SET(S) ->
RT = ?TYPE(R),
ST = ?TYPE(S),
@@ -812,6 +1053,10 @@ drestriction(SetFun, S1, S2) when ?IS_SET(S1), ?IS_SET(S2) ->
end
end.
+-spec(projection(SetFun, Set1) -> Set2 when
+ SetFun :: set_fun(),
+ Set1 :: a_set(),
+ Set2 :: a_set()).
projection(I, Set) when is_integer(I), ?IS_SET(Set) ->
Type = ?TYPE(Set),
case check_for_sort(Type, I) of
@@ -827,6 +1072,10 @@ projection(I, Set) when is_integer(I), ?IS_SET(Set) ->
projection(Fun, Set) ->
range(substitution(Fun, Set)).
+-spec(substitution(SetFun, Set1) -> Set2 when
+ SetFun :: set_fun(),
+ Set1 :: a_set(),
+ Set2 :: a_set()).
substitution(I, Set) when is_integer(I), ?IS_SET(Set) ->
Type = ?TYPE(Set),
case check_for_sort(Type, I) of
@@ -867,11 +1116,18 @@ substitution(SetFun, Set) when ?IS_SET(Set) ->
end
end.
+-spec(partition(SetOfSets) -> Partition when
+ SetOfSets :: set_of_sets(),
+ Partition :: a_set()).
partition(Sets) ->
F1 = relation_to_family(canonical_relation(Sets)),
F2 = relation_to_family(converse(F1)),
range(F2).
+-spec(partition(SetFun, Set) -> Partition when
+ SetFun :: set_fun(),
+ Partition :: a_set(),
+ Set :: a_set()).
partition(I, Set) when is_integer(I), ?IS_SET(Set) ->
Type = ?TYPE(Set),
case check_for_sort(Type, I) of
@@ -887,6 +1143,12 @@ partition(I, Set) when is_integer(I), ?IS_SET(Set) ->
partition(Fun, Set) ->
range(partition_family(Fun, Set)).
+-spec(partition(SetFun, Set1, Set2) -> {Set3, Set4} when
+ SetFun :: set_fun(),
+ Set1 :: a_set(),
+ Set2 :: a_set(),
+ Set3 :: a_set(),
+ Set4 :: a_set()).
partition(I, R, S) when is_integer(I), ?IS_SET(R), ?IS_SET(S) ->
RT = ?TYPE(R),
ST = ?TYPE(S),
@@ -954,21 +1216,32 @@ partition(SetFun, S1, S2) when ?IS_SET(S1), ?IS_SET(S2) ->
end
end.
+-spec(multiple_relative_product(TupleOfBinRels, BinRel1) -> BinRel2 when
+ TupleOfBinRels :: tuple_of(BinRel),
+ BinRel :: binary_relation(),
+ BinRel1 :: binary_relation(),
+ BinRel2 :: binary_relation()).
multiple_relative_product(T, R) when is_tuple(T), ?IS_SET(R) ->
case test_rel(R, tuple_size(T), eq) of
true when ?TYPE(R) =:= ?ANYTYPE ->
empty_set();
- true ->
+ true ->
MProd = mul_relprod(tuple_to_list(T), 1, R),
- relative_product(list_to_tuple(MProd));
- false ->
+ relative_product(MProd);
+ false ->
erlang:error(badarg, [T, R])
end.
-join(R1, I1, R2, I2)
+-spec(join(Relation1, I, Relation2, J) -> Relation3 when
+ Relation1 :: relation(),
+ Relation2 :: relation(),
+ Relation3 :: relation(),
+ I :: pos_integer(),
+ J :: pos_integer()).
+join(R1, I1, R2, I2)
when ?IS_SET(R1), ?IS_SET(R2), is_integer(I1), is_integer(I2) ->
case test_rel(R1, I1, lte) and test_rel(R2, I2, lte) of
- false ->
+ false ->
erlang:error(badarg, [R1, I1, R2, I2]);
true when ?TYPE(R1) =:= ?ANYTYPE -> R1;
true when ?TYPE(R2) =:= ?ANYTYPE -> R2;
@@ -980,8 +1253,8 @@ join(R1, I1, R2, I2)
true ->
fun({X,Y}) -> join_element(X, Y) end;
false ->
- fun({X,Y}) ->
- list_to_tuple(join_element(X, Y, I2))
+ fun({X,Y}) ->
+ list_to_tuple(join_element(X, Y, I2))
end
end,
?SET(replace(T, F, []), F({?TYPE(R1), ?TYPE(R2)}))
@@ -1001,9 +1274,15 @@ test_rel(R, I, C) ->
%%% Family functions
%%%
+-spec(fam2rel(Family) -> BinRel when
+ Family :: family(),
+ BinRel :: binary_relation()).
fam2rel(F) ->
family_to_relation(F).
+-spec(family_to_relation(Family) -> BinRel when
+ Family :: family(),
+ BinRel :: binary_relation()).
%% Inlined.
family_to_relation(F) when ?IS_SET(F) ->
case ?TYPE(F) of
@@ -1013,6 +1292,10 @@ family_to_relation(F) when ?IS_SET(F) ->
_ -> erlang:error(badarg, [F])
end.
+-spec(family_specification(Fun, Family1) -> Family2 when
+ Fun :: spec_fun(),
+ Family1 :: family(),
+ Family2 :: family()).
family_specification(Fun, F) when ?IS_SET(F) ->
case ?TYPE(F) of
?FAMILY(_DT, Type) = FType ->
@@ -1032,6 +1315,9 @@ family_specification(Fun, F) when ?IS_SET(F) ->
_ -> erlang:error(badarg, [Fun, F])
end.
+-spec(union_of_family(Family) -> Set when
+ Family :: family(),
+ Set :: a_set()).
union_of_family(F) when ?IS_SET(F) ->
case ?TYPE(F) of
?FAMILY(_DT, Type) ->
@@ -1040,6 +1326,9 @@ union_of_family(F) when ?IS_SET(F) ->
_ -> erlang:error(badarg, [F])
end.
+-spec(intersection_of_family(Family) -> Set when
+ Family :: family(),
+ Set :: a_set()).
intersection_of_family(F) when ?IS_SET(F) ->
case ?TYPE(F) of
?FAMILY(_DT, Type) ->
@@ -1052,6 +1341,9 @@ intersection_of_family(F) when ?IS_SET(F) ->
_ -> erlang:error(badarg, [F])
end.
+-spec(family_union(Family1) -> Family2 when
+ Family1 :: family(),
+ Family2 :: family()).
family_union(F) when ?IS_SET(F) ->
case ?TYPE(F) of
?FAMILY(DT, ?SET_OF(Type)) ->
@@ -1060,6 +1352,9 @@ family_union(F) when ?IS_SET(F) ->
_ -> erlang:error(badarg, [F])
end.
+-spec(family_intersection(Family1) -> Family2 when
+ Family1 :: family(),
+ Family2 :: family()).
family_intersection(F) when ?IS_SET(F) ->
case ?TYPE(F) of
?FAMILY(DT, ?SET_OF(Type)) ->
@@ -1073,6 +1368,9 @@ family_intersection(F) when ?IS_SET(F) ->
_ -> erlang:error(badarg, [F])
end.
+-spec(family_domain(Family1) -> Family2 when
+ Family1 :: family(),
+ Family2 :: family()).
family_domain(F) when ?IS_SET(F) ->
case ?TYPE(F) of
?FAMILY(FDT, ?BINREL(DT, _)) ->
@@ -1082,6 +1380,9 @@ family_domain(F) when ?IS_SET(F) ->
_ -> erlang:error(badarg, [F])
end.
+-spec(family_range(Family1) -> Family2 when
+ Family1 :: family(),
+ Family2 :: family()).
family_range(F) when ?IS_SET(F) ->
case ?TYPE(F) of
?FAMILY(DT, ?BINREL(_, RT)) ->
@@ -1091,15 +1392,30 @@ family_range(F) when ?IS_SET(F) ->
_ -> erlang:error(badarg, [F])
end.
+-spec(family_field(Family1) -> Family2 when
+ Family1 :: family(),
+ Family2 :: family()).
family_field(F) ->
family_union(family_domain(F), family_range(F)).
+-spec(family_union(Family1, Family2) -> Family3 when
+ Family1 :: family(),
+ Family2 :: family(),
+ Family3 :: family()).
family_union(F1, F2) ->
fam_binop(F1, F2, fun fam_union/3).
+-spec(family_intersection(Family1, Family2) -> Family3 when
+ Family1 :: family(),
+ Family2 :: family(),
+ Family3 :: family()).
family_intersection(F1, F2) ->
fam_binop(F1, F2, fun fam_intersect/3).
+-spec(family_difference(Family1, Family2) -> Family3 when
+ Family1 :: family(),
+ Family2 :: family(),
+ Family3 :: family()).
family_difference(F1, F2) ->
fam_binop(F1, F2, fun fam_difference/3).
@@ -1108,13 +1424,17 @@ fam_binop(F1, F2, FF) when ?IS_SET(F1), ?IS_SET(F2) ->
case unify_types(?TYPE(F1), ?TYPE(F2)) of
[] ->
erlang:error(type_mismatch, [F1, F2]);
- ?ANYTYPE ->
+ ?ANYTYPE ->
F1;
- Type = ?FAMILY(_, _) ->
+ Type = ?FAMILY(_, _) ->
?SET(FF(?LIST(F1), ?LIST(F2), []), Type);
_ -> erlang:error(badarg, [F1, F2])
end.
+-spec(partition_family(SetFun, Set) -> Family when
+ Family :: family(),
+ SetFun :: set_fun(),
+ Set :: a_set()).
partition_family(I, Set) when is_integer(I), ?IS_SET(Set) ->
Type = ?TYPE(Set),
case check_for_sort(Type, I) of
@@ -1159,8 +1479,12 @@ partition_family(SetFun, Set) when ?IS_SET(Set) ->
end
end.
+-spec(family_projection(SetFun, Family1) -> Family2 when
+ SetFun :: set_fun(),
+ Family1 :: family(),
+ Family2 :: family()).
family_projection(SetFun, F) when ?IS_SET(F) ->
- case ?TYPE(F) of
+ case ?TYPE(F) of
?FAMILY(_, _) when [] =:= ?LIST(F) ->
empty_set();
?FAMILY(DT, Type) ->
@@ -1172,7 +1496,7 @@ family_projection(SetFun, F) when ?IS_SET(F) ->
Bad ->
erlang:error(Bad, [SetFun, F])
end;
- _ ->
+ _ ->
erlang:error(badarg, [SetFun, F])
end;
?ANYTYPE -> F;
@@ -1183,6 +1507,9 @@ family_projection(SetFun, F) when ?IS_SET(F) ->
%%% Digraph functions
%%%
+-spec(family_to_digraph(Family) -> Graph when
+ Graph :: digraph(),
+ Family :: family()).
family_to_digraph(F) when ?IS_SET(F) ->
case ?TYPE(F) of
?FAMILY(_, _) -> fam2digraph(F, digraph:new());
@@ -1190,6 +1517,10 @@ family_to_digraph(F) when ?IS_SET(F) ->
_Else -> erlang:error(badarg, [F])
end.
+-spec(family_to_digraph(Family, GraphType) -> Graph when
+ Graph :: digraph(),
+ Family :: family(),
+ GraphType :: [digraph:d_type()]).
family_to_digraph(F, Type) when ?IS_SET(F) ->
case ?TYPE(F) of
?FAMILY(_, _) -> ok;
@@ -1208,12 +1539,19 @@ family_to_digraph(F, Type) when ?IS_SET(F) ->
error:badarg -> erlang:error(badarg, [F, Type])
end.
+-spec(digraph_to_family(Graph) -> Family when
+ Graph :: digraph(),
+ Family :: family()).
digraph_to_family(G) ->
case catch digraph_family(G) of
{'EXIT', _} -> erlang:error(badarg, [G]);
L -> ?SET(L, ?FAMILY(?ATOM_TYPE, ?ATOM_TYPE))
end.
+-spec(digraph_to_family(Graph, Type) -> Family when
+ Graph :: digraph(),
+ Family :: family(),
+ Type :: type()).
digraph_to_family(G, T) ->
case {is_type(T), T} of
{true, ?SET_OF(?FAMILY(_,_) = Type)} ->
@@ -1284,7 +1622,7 @@ rel(Ts, [Type]) ->
end;
rel(Ts, Sz) ->
rel(Ts, Sz, erlang:make_tuple(Sz, ?ATOM_TYPE)).
-
+
atoms_only(Type, I) when ?IS_ATOM_TYPE(?REL_TYPE(I, Type)) ->
atoms_only(Type, I+1);
atoms_only(Type, I) when I > tuple_size(Type), ?IS_RELATION(Type) ->
@@ -1312,7 +1650,7 @@ rel_type([], SL, Type) when ?IS_RELATION(Type) ->
%% Inlined.
a_func(Ts, T) ->
case {T, is_type(T)} of
- {[?BINREL(DT, RT) = Type], true} when ?IS_ATOM_TYPE(DT),
+ {[?BINREL(DT, RT) = Type], true} when ?IS_ATOM_TYPE(DT),
?IS_ATOM_TYPE(RT) ->
func(Ts, Type);
{[Type], true} ->
@@ -1333,16 +1671,16 @@ func([], _X0, L, Type) ->
%% Inlined.
fam(Ts, T) ->
case {T, is_type(T)} of
- {[?FAMILY(DT, RT) = Type], true} when ?IS_ATOM_TYPE(DT),
+ {[?FAMILY(DT, RT) = Type], true} when ?IS_ATOM_TYPE(DT),
?IS_ATOM_TYPE(RT) ->
fam2(Ts, Type);
{[Type], true} ->
func_type(Ts, [], Type, fun(?FAMILY(_,_)) -> true end)
end.
-fam2([], Type) ->
+fam2([], Type) ->
?SET([], Type);
-fam2(Ts, Type) ->
+fam2(Ts, Type) ->
fam2(sort(Ts), Ts, [], Type).
fam2([{I,L} | T], I0, SL, Type) when I /= I0 ->
@@ -1383,7 +1721,7 @@ setify(E, Type0) ->
{Type, OrdSet} = make_element(E, Type0, Type0),
?ORDSET(OrdSet, Type).
-is_no_lists(T) when is_tuple(T) ->
+is_no_lists(T) when is_tuple(T) ->
Sz = tuple_size(T),
is_no_lists(T, Sz, Sz, []).
@@ -1404,7 +1742,7 @@ create([], T, _T0, L) ->
make_element(C, ?ANYTYPE, _T0) ->
make_element(C);
-make_element(C, Atom, ?ANYTYPE) when ?IS_ATOM_TYPE(Atom),
+make_element(C, Atom, ?ANYTYPE) when ?IS_ATOM_TYPE(Atom),
not is_list(C), not is_tuple(C) ->
{Atom, C};
make_element(C, Atom, Atom) when ?IS_ATOM_TYPE(Atom) ->
@@ -1585,12 +1923,12 @@ sympart([H1 | T1], [H2 | T2], L1, L12, L2, T) when H1 == H2 ->
sympart([H1 | T1], [H2 | T2], L1, L12, L2, T) ->
sympart2(T1, T2, L1, L12, [H2 | L2], T, H1);
sympart(S1, [], L1, L12, L2, T) ->
- {?SET(reverse(L1, S1), T),
- ?SET(reverse(L12), T),
+ {?SET(reverse(L1, S1), T),
+ ?SET(reverse(L12), T),
?SET(reverse(L2), T)};
sympart(_, S2, L1, L12, L2, T) ->
- {?SET(reverse(L1), T),
- ?SET(reverse(L12), T),
+ {?SET(reverse(L1), T),
+ ?SET(reverse(L12), T),
?SET(reverse(L2, S2), T)}.
sympart1([H1 | T1], T2, L1, L12, L2, T, H2) when H1 < H2 ->
@@ -1600,8 +1938,8 @@ sympart1([H1 | T1], T2, L1, L12, L2, T, H2) when H1 == H2 ->
sympart1([H1 | T1], T2, L1, L12, L2, T, H2) ->
sympart2(T1, T2, L1, L12, [H2 | L2], T, H1);
sympart1(_, T2, L1, L12, L2, T, H2) ->
- {?SET(reverse(L1), T),
- ?SET(reverse(L12), T),
+ {?SET(reverse(L1), T),
+ ?SET(reverse(L12), T),
?SET(reverse(L2, [H2 | T2]), T)}.
sympart2(T1, [H2 | T2], L1, L12, L2, T, H1) when H1 > H2 ->
@@ -1611,8 +1949,8 @@ sympart2(T1, [H2 | T2], L1, L12, L2, T, H1) when H1 == H2 ->
sympart2(T1, [H2 | T2], L1, L12, L2, T, H1) ->
sympart1(T1, T2, [H1 | L1], L12, L2, T, H2);
sympart2(T1, _, L1, L12, L2, T, H1) ->
- {?SET(reverse(L1, [H1 | T1]), T),
- ?SET(reverse(L12), T),
+ {?SET(reverse(L1, [H1 | T1]), T),
+ ?SET(reverse(L12), T),
?SET(reverse(L2), T)}.
prod([[E | Es] | Xs], T, L) ->
@@ -1660,7 +1998,7 @@ lunion([[] | Ls]) ->
lunion(Ls);
lunion([S | Ss]) ->
umerge(lunion(Ss, last(S), [S], []));
-lunion([]) ->
+lunion([]) ->
[].
lunion([[E] = S | Ss], Last, SL, Ls) when E > Last -> % optimization
@@ -1669,7 +2007,7 @@ lunion([S | Ss], Last, SL, Ls) when hd(S) > Last ->
lunion(Ss, last(S), [S | SL], Ls);
lunion([S | Ss], _Last, SL, Ls) ->
lunion(Ss, last(S), [S], [append(reverse(SL)) | Ls]);
-lunion([], _Last, SL, Ls) ->
+lunion([], _Last, SL, Ls) ->
[append(reverse(SL)) | Ls].
%% The empty list is always the first list, if present.
@@ -1752,18 +2090,17 @@ relprod(B0, Bx0, By0, A0, L, Ax, [{Bx,By} | B], Ay) when Ay == Bx ->
relprod(B0, Bx0, By0, A0, L, _Ax, _B, _Ay) ->
relprod2(B0, Bx0, By0, A0, L).
-relprod_n({}, _R, _EmptyG, _IsR) ->
+relprod_n([], _R, _EmptyG, _IsR) ->
{error, badarg};
-relprod_n(RT, R, EmptyR, IsR) ->
- RL = tuple_to_list(RT),
+relprod_n(RL, R, EmptyR, IsR) ->
case domain_type(RL, ?ANYTYPE) of
- Error = {error, _Reason} ->
+ Error = {error, _Reason} ->
Error;
DType ->
Empty = any(fun is_empty_set/1, RL) or EmptyR,
RType = range_type(RL, []),
Type = ?BINREL(DType, RType),
- Prod =
+ Prod =
case Empty of
true when DType =:= ?ANYTYPE; RType =:= ?ANYTYPE ->
empty_set();
@@ -1771,7 +2108,7 @@ relprod_n(RT, R, EmptyR, IsR) ->
?SET([], Type);
false ->
TL = ?LIST((relprod_n(RL))),
- Sz = tuple_size(RT),
+ Sz = length(RL),
Fun = fun({X,A}) -> {X, flat(Sz, A, [])} end,
?SET(map(Fun, TL), Type)
end,
@@ -1799,12 +2136,12 @@ flat(N, {T,A}, L) ->
domain_type([T | Ts], T0) when ?IS_SET(T) ->
case ?TYPE(T) of
- ?BINREL(DT, _RT) ->
+ ?BINREL(DT, _RT) ->
case unify_types(DT, T0) of
[] -> {error, type_mismatch};
T1 -> domain_type(Ts, T1)
end;
- ?ANYTYPE ->
+ ?ANYTYPE ->
domain_type(Ts, T0);
_ -> {error, badarg}
end;
@@ -1813,12 +2150,12 @@ domain_type([], T0) ->
range_type([T | Ts], L) ->
case ?TYPE(T) of
- ?BINREL(_DT, RT) ->
+ ?BINREL(_DT, RT) ->
range_type(Ts, [RT | L]);
- ?ANYTYPE ->
+ ?ANYTYPE ->
?ANYTYPE
end;
-range_type([], L) ->
+range_type([], L) ->
list_to_tuple(reverse(L)).
converse([{A,B} | X], L) ->
@@ -1861,7 +2198,7 @@ weak1([E={X,_Y} | Es], Ys, L, X0) when X == X0 -> % when X < Y
weak1(Es, Ys, L, X) ->
weak(Es, Ys, [{X,X} | L]).
-weak2([E={X,_Y} | Es], Ys, L, X0) when X == X0 -> % when X < _Y
+weak2([E={X,_Y} | Es], Ys, L, X0) when X == X0 -> % when X < _Y
weak2(Es, Ys, [E | L], X);
weak2(Es, Ys, L, _X) ->
weak(Es, Ys, L).
@@ -1910,7 +2247,7 @@ restrict_n(I, [T | Ts], Key, Keys, L) ->
end;
restrict_n(_I, _Ts, _Key, _Keys, L) ->
L.
-
+
restrict_n(I, K, Ts, [Key | Keys], L, E) when K > Key ->
restrict_n(I, K, Ts, Keys, L, E);
restrict_n(I, K, Ts, [Key | Keys], L, E) when K == Key ->
@@ -1933,7 +2270,7 @@ restrict([{K,E} | Ts], _Key, Keys, L) ->
restrict(Ts, K, Keys, L, E);
restrict(_Ts, _Key, _Keys, L) ->
L.
-
+
restrict(Ts, K, [Key | Keys], L, E) when K > Key ->
restrict(Ts, K, Keys, L, E);
restrict(Ts, K, [Key | Keys], L, E) when K == Key ->
@@ -1956,7 +2293,7 @@ diff_restrict_n(I, _Ts, _Key, _Keys, L) when I =:= 1 ->
reverse(L);
diff_restrict_n(_I, _Ts, _Key, _Keys, L) ->
sort(L).
-
+
diff_restrict_n(I, K, Ts, [Key | Keys], L, T) when K > Key ->
diff_restrict_n(I, K, Ts, Keys, L, T);
diff_restrict_n(I, K, Ts, [Key | Keys], L, _T) when K == Key ->
@@ -1981,7 +2318,7 @@ diff_restrict([{K,E} | Ts], _Key, Keys, L) ->
diff_restrict(Ts, K, Keys, L, E);
diff_restrict(_Ts, _Key, _Keys, L) ->
L.
-
+
diff_restrict(Ts, K, [Key | Keys], L, E) when K > Key ->
diff_restrict(Ts, K, Keys, L, E);
diff_restrict(Ts, K, [Key | Keys], L, _E) when K == Key ->
@@ -2041,7 +2378,7 @@ external_fun({external, Function}) when is_atom(Function) ->
false;
external_fun({external, Fun}) ->
Fun;
-external_fun(_) ->
+external_fun(_) ->
false.
%% Inlined.
@@ -2121,7 +2458,7 @@ partition3_n(I, _Ts, _Key, _Keys, L1, L2) when I =:= 1 ->
[reverse(L1) | reverse(L2)];
partition3_n(_I, _Ts, _Key, _Keys, L1, L2) ->
[sort(L1) | sort(L2)].
-
+
partition3_n(I, K, Ts, [Key | Keys], L1, L2, T) when K > Key ->
partition3_n(I, K, Ts, Keys, L1, L2, T);
partition3_n(I, K, Ts, [Key | Keys], L1, L2, T) when K == Key ->
@@ -2146,7 +2483,7 @@ partition3([{K,E} | Ts], _Key, Keys, L1, L2) ->
partition3(Ts, K, Keys, L1, L2, E);
partition3(_Ts, _Key, _Keys, L1, L2) ->
[L1 | L2].
-
+
partition3(Ts, K, [Key | Keys], L1, L2, E) when K > Key ->
partition3(Ts, K, Keys, L1, L2, E);
partition3(Ts, K, [Key | Keys], L1, L2, E) when K == Key ->
@@ -2192,7 +2529,7 @@ join_element(E1, E2, I2) ->
join_element2([B | Bs], C, I2) when C =/= I2 ->
[B | join_element2(Bs, C+1, I2)];
-join_element2([_ | Bs], _C, _I2) ->
+join_element2([_ | Bs], _C, _I2) ->
Bs.
family2rel([{X,S} | F], L) ->
@@ -2297,7 +2634,7 @@ check_function([{X,_} | XL], R) ->
check_function(X, XL, R);
check_function([], R) ->
R.
-
+
check_function(X0, [{X,_} | XL], R) when X0 /= X ->
check_function(X, XL, R);
check_function(X0, [{X,_} | _XL], _R) when X0 == X ->
@@ -2371,14 +2708,14 @@ term2set(T, Type) ->
?ORDSET(T, Type).
fam2digraph(F, G) ->
- Fun = fun({From, ToL}) ->
+ Fun = fun({From, ToL}) ->
digraph:add_vertex(G, From),
Fun2 = fun(To) ->
digraph:add_vertex(G, To),
case digraph:add_edge(G, From, To) of
- {error, {bad_edge, _}} ->
+ {error, {bad_edge, _}} ->
throw({error, cyclic});
- _ ->
+ _ ->
true
end
end,
@@ -2397,7 +2734,7 @@ digraph_fam([V | Vs], V0, G, L) when V /= V0 ->
digraph_fam([], _V0, _G, L) ->
reverse(L).
-%% -> bool()
+%% -> boolean()
check_fun(T, F, FunT) ->
true = is_type(FunT),
{NT, _MaxI} = number_tuples(T, 1),
@@ -2424,7 +2761,7 @@ check_for_sort(T, _I) when T =:= ?ANYTYPE ->
check_for_sort(T, I) when ?IS_RELATION(T), I =< ?REL_ARITY(T), I >= 1 ->
I > 1;
check_for_sort(_T, _I) ->
- error.
+ error.
inverse_substitution(L, Fun, Sort) ->
%% One easily sees that the inverse of the tuples created by
@@ -2477,11 +2814,11 @@ match_types(Type1, Type2) -> match_types1(Type1, Type2).
match_types1(Atom, Atom) when ?IS_ATOM_TYPE(Atom) ->
true;
-match_types1(?ANYTYPE, _) ->
+match_types1(?ANYTYPE, _) ->
true;
-match_types1(_, ?ANYTYPE) ->
+match_types1(_, ?ANYTYPE) ->
true;
-match_types1(?SET_OF(Type1), ?SET_OF(Type2)) ->
+match_types1(?SET_OF(Type1), ?SET_OF(Type2)) ->
match_types1(Type1, Type2);
match_types1(T1, T2) when tuple_size(T1) =:= tuple_size(T2) ->
match_typesl(tuple_size(T1), T1, T2);
diff --git a/lib/stdlib/src/string.erl b/lib/stdlib/src/string.erl
index 264348180f..30eac4f07d 100644
--- a/lib/stdlib/src/string.erl
+++ b/lib/stdlib/src/string.erl
@@ -29,23 +29,23 @@
%%---------------------------------------------------------------------------
--type direction() :: 'left' | 'right' | 'both'.
-
-%%---------------------------------------------------------------------------
-
%% Robert's bit
%% len(String)
%% Return the length of a string.
--spec len(string()) -> non_neg_integer().
+-spec len(String) -> Length when
+ String :: string(),
+ Length :: non_neg_integer().
len(S) -> length(S).
%% equal(String1, String2)
%% Test if 2 strings are equal.
--spec equal(string(), string()) -> boolean().
+-spec equal(String1, String2) -> boolean() when
+ String1 :: string(),
+ String2 :: string().
equal(S, S) -> true;
equal(_, _) -> false.
@@ -53,7 +53,10 @@ equal(_, _) -> false.
%% concat(String1, String2)
%% Concatenate 2 strings.
--spec concat(string(), string()) -> string().
+-spec concat(String1, String2) -> String3 when
+ String1 :: string(),
+ String2 :: string(),
+ String3 :: string().
concat(S1, S2) -> S1 ++ S2.
@@ -61,7 +64,10 @@ concat(S1, S2) -> S1 ++ S2.
%% rchr(String, Char)
%% Return the first/last index of the character in a string.
--spec chr(string(), char()) -> non_neg_integer().
+-spec chr(String, Character) -> Index when
+ String :: string(),
+ Character :: char(),
+ Index :: non_neg_integer().
chr(S, C) when is_integer(C) -> chr(S, C, 1).
@@ -69,7 +75,10 @@ chr([C|_Cs], C, I) -> I;
chr([_|Cs], C, I) -> chr(Cs, C, I+1);
chr([], _C, _I) -> 0.
--spec rchr(string(), char()) -> non_neg_integer().
+-spec rchr(String, Character) -> Index when
+ String :: string(),
+ Character :: char(),
+ Index :: non_neg_integer().
rchr(S, C) when is_integer(C) -> rchr(S, C, 1, 0).
@@ -85,7 +94,10 @@ rchr([], _C, _I, L) -> L.
%% Return the first/last index of the sub-string in a string.
%% index/2 is kept for backwards compatibility.
--spec str(string(), string()) -> non_neg_integer().
+-spec str(String, SubString) -> Index when
+ String :: string(),
+ SubString :: string(),
+ Index :: non_neg_integer().
str(S, Sub) when is_list(Sub) -> str(S, Sub, 1).
@@ -97,7 +109,10 @@ str([C|S], [C|Sub], I) ->
str([_|S], Sub, I) -> str(S, Sub, I+1);
str([], _Sub, _I) -> 0.
--spec rstr(string(), string()) -> non_neg_integer().
+-spec rstr(String, SubString) -> Index when
+ String :: string(),
+ SubString :: string(),
+ Index :: non_neg_integer().
rstr(S, Sub) when is_list(Sub) -> rstr(S, Sub, 1, 0).
@@ -116,7 +131,10 @@ prefix(Pre, String) when is_list(Pre), is_list(String) -> false.
%% span(String, Chars) -> Length.
%% cspan(String, Chars) -> Length.
--spec span(string(), string()) -> non_neg_integer().
+-spec span(String, Chars) -> Length when
+ String :: string(),
+ Chars :: string(),
+ Length :: non_neg_integer().
span(S, Cs) when is_list(Cs) -> span(S, Cs, 0).
@@ -127,7 +145,10 @@ span([C|S], Cs, I) ->
end;
span([], _Cs, I) -> I.
--spec cspan(string(), string()) -> non_neg_integer().
+-spec cspan(String, Chars) -> Length when
+ String :: string(),
+ Chars :: string(),
+ Length :: non_neg_integer().
cspan(S, Cs) when is_list(Cs) -> cspan(S, Cs, 0).
@@ -142,14 +163,21 @@ cspan([], _Cs, I) -> I.
%% substr(String, Start, Length)
%% Extract a sub-string from String.
--spec substr(string(), pos_integer()) -> string().
+-spec substr(String, Start) -> SubString when
+ String :: string(),
+ SubString :: string(),
+ Start :: pos_integer().
substr(String, 1) when is_list(String) ->
String;
substr(String, S) when is_integer(S), S > 1 ->
substr2(String, S).
--spec substr(string(), pos_integer(), non_neg_integer()) -> string().
+-spec substr(String, Start, Length) -> SubString when
+ String :: string(),
+ SubString :: string(),
+ Start :: pos_integer(),
+ Length :: non_neg_integer().
substr(String, S, L) when is_integer(S), S >= 1, is_integer(L), L >= 0 ->
substr1(substr2(String, S), L).
@@ -163,7 +191,10 @@ substr2([_|String], S) -> substr2(String, S-1).
%% tokens(String, Seperators).
%% Return a list of tokens seperated by characters in Seperators.
--spec tokens(string(), string()) -> [[char(),...]].
+-spec tokens(String, SeparatorList) -> Tokens when
+ String :: string(),
+ SeparatorList :: string(),
+ Tokens :: [Token :: nonempty_string()].
tokens(S, Seps) ->
tokens1(S, Seps, []).
@@ -184,11 +215,18 @@ tokens2([C|S], Seps, Toks, Cs) ->
tokens2([], _Seps, Toks, Cs) ->
reverse([reverse(Cs)|Toks]).
--spec chars(char(), non_neg_integer()) -> string().
+-spec chars(Character, Number) -> String when
+ Character :: char(),
+ Number :: non_neg_integer(),
+ String :: string().
chars(C, N) -> chars(C, N, []).
--spec chars(char(), non_neg_integer(), string()) -> string().
+-spec chars(Character, Number, Tail) -> String when
+ Character :: char(),
+ Number :: non_neg_integer(),
+ Tail :: string(),
+ String :: string().
chars(C, N, Tail) when N > 0 ->
chars(C, N-1, [C|Tail]);
@@ -199,7 +237,10 @@ chars(C, 0, Tail) when is_integer(C) ->
%%% COPIES %%%
--spec copies(string(), non_neg_integer()) -> string().
+-spec copies(String, Number) -> Copies when
+ String :: string(),
+ Copies :: string(),
+ Number :: non_neg_integer().
copies(CharList, Num) when is_list(CharList), is_integer(Num), Num >= 0 ->
copies(CharList, Num, []).
@@ -211,11 +252,16 @@ copies(CharList, Num, R) ->
%%% WORDS %%%
--spec words(string()) -> pos_integer().
+-spec words(String) -> Count when
+ String :: string(),
+ Count :: pos_integer().
words(String) -> words(String, $\s).
--spec words(string(), char()) -> pos_integer().
+-spec words(String, Character) -> Count when
+ String :: string(),
+ Character :: char(),
+ Count :: pos_integer().
words(String, Char) when is_integer(Char) ->
w_count(strip(String, both, Char), Char, 0).
@@ -226,11 +272,18 @@ w_count([_H|T], Char, Num) -> w_count(T, Char, Num).
%%% SUB_WORDS %%%
--spec sub_word(string(), integer()) -> string().
+-spec sub_word(String, Number) -> Word when
+ String :: string(),
+ Word :: string(),
+ Number :: integer().
sub_word(String, Index) -> sub_word(String, Index, $\s).
--spec sub_word(string(), integer(), char()) -> string().
+-spec sub_word(String, Number, Character) -> Word when
+ String :: string(),
+ Word :: string(),
+ Number :: integer(),
+ Character :: char().
sub_word(String, Index, Char) when is_integer(Index), is_integer(Char) ->
case words(String, Char) of
@@ -254,14 +307,21 @@ s_word([_|T],Stop,Char,Index,Res) when Index < Stop ->
strip(String) -> strip(String, both).
--spec strip(string(), direction()) -> string().
+-spec strip(String, Direction) -> Stripped when
+ String :: string(),
+ Stripped :: string(),
+ Direction :: left | right | both.
strip(String, left) -> strip_left(String, $\s);
strip(String, right) -> strip_right(String, $\s);
strip(String, both) ->
strip_right(strip_left(String, $\s), $\s).
--spec strip(string(), direction(), char()) -> string().
+-spec strip(String, Direction, Character) -> Stripped when
+ String :: string(),
+ Stripped :: string(),
+ Direction :: left | right | both,
+ Character :: char().
strip(String, right, Char) -> strip_right(String, Char);
strip(String, left, Char) -> strip_left(String, Char);
@@ -285,11 +345,18 @@ strip_right([], Sc) when is_integer(Sc) ->
%%% LEFT %%%
--spec left(string(), non_neg_integer()) -> string().
+-spec left(String, Number) -> Left when
+ String :: string(),
+ Left :: string(),
+ Number :: non_neg_integer().
left(String, Len) when is_integer(Len) -> left(String, Len, $\s).
--spec left(string(), non_neg_integer(), char()) -> string().
+-spec left(String, Number, Character) -> Left when
+ String :: string(),
+ Left :: string(),
+ Number :: non_neg_integer(),
+ Character :: char().
left(String, Len, Char) when is_integer(Char) ->
Slen = length(String),
@@ -303,11 +370,18 @@ l_pad(String, Num, Char) -> String ++ chars(Char, Num).
%%% RIGHT %%%
--spec right(string(), non_neg_integer()) -> string().
+-spec right(String, Number) -> Right when
+ String :: string(),
+ Right :: string(),
+ Number :: non_neg_integer().
right(String, Len) when is_integer(Len) -> right(String, Len, $\s).
--spec right(string(), non_neg_integer(), char()) -> string().
+-spec right(String, Number, Character) -> Right when
+ String :: string(),
+ Right :: string(),
+ Number :: non_neg_integer(),
+ Character :: char().
right(String, Len, Char) when is_integer(Char) ->
Slen = length(String),
@@ -321,11 +395,18 @@ r_pad(String, Num, Char) -> chars(Char, Num, String).
%%% CENTRE %%%
--spec centre(string(), non_neg_integer()) -> string().
+-spec centre(String, Number) -> Centered when
+ String :: string(),
+ Centered :: string(),
+ Number :: non_neg_integer().
centre(String, Len) when is_integer(Len) -> centre(String, Len, $\s).
--spec centre(string(), non_neg_integer(), char()) -> string().
+-spec centre(String, Number, Character) -> Centered when
+ String :: string(),
+ Centered :: string(),
+ Number :: non_neg_integer(),
+ Character :: char().
centre(String, 0, Char) when is_list(String), is_integer(Char) ->
[]; % Strange cases to centre string
@@ -341,11 +422,18 @@ centre(String, Len, Char) when is_integer(Char) ->
%%% SUB_STRING %%%
--spec sub_string(string(), pos_integer()) -> string().
+-spec sub_string(String, Start) -> SubString when
+ String :: string(),
+ SubString :: string(),
+ Start :: pos_integer().
sub_string(String, Start) -> substr(String, Start).
--spec sub_string(string(), pos_integer(), pos_integer()) -> string().
+-spec sub_string(String, Start, Stop) -> SubString when
+ String :: string(),
+ SubString :: string(),
+ Start :: pos_integer(),
+ Stop :: pos_integer().
sub_string(String, Start, Stop) -> substr(String, Start, Stop - Start + 1).
@@ -370,23 +458,34 @@ to_upper_char(C) when is_integer(C), 16#F8 =< C, C =< 16#FE ->
to_upper_char(C) ->
C.
--spec to_lower(string()) -> string()
- ; (char()) -> char().
+-spec to_lower(String) -> Result when
+ String :: string(),
+ Result :: string()
+ ; (Char) -> CharResult when
+ Char :: char(),
+ CharResult :: char().
to_lower(S) when is_list(S) ->
[to_lower_char(C) || C <- S];
to_lower(C) when is_integer(C) ->
to_lower_char(C).
--spec to_upper(string()) -> string()
- ; (char()) -> char().
+-spec to_upper(String) -> Result when
+ String :: string(),
+ Result :: string()
+ ; (Char) -> CharResult when
+ Char :: char(),
+ CharResult :: char().
to_upper(S) when is_list(S) ->
[to_upper_char(C) || C <- S];
to_upper(C) when is_integer(C) ->
to_upper_char(C).
--spec join([string()], string()) -> string().
+-spec join(StringList, Separator) -> String when
+ StringList :: [string()],
+ Separator :: string(),
+ String :: string().
join([], Sep) when is_list(Sep) ->
[];
diff --git a/lib/stdlib/src/supervisor.erl b/lib/stdlib/src/supervisor.erl
index 09a01a9aea..e60706ed05 100644
--- a/lib/stdlib/src/supervisor.erl
+++ b/lib/stdlib/src/supervisor.erl
@@ -35,19 +35,28 @@
%%--------------------------------------------------------------------------
--export_type([child_spec/0, del_err/0, startchild_ret/0, strategy/0]).
+-export_type([child_spec/0, startchild_ret/0, strategy/0]).
%%--------------------------------------------------------------------------
--type child_id() :: pid() | 'undefined'.
--type mfargs() :: {module(), atom(), [term()] | undefined}.
+-type child() :: pid() | 'undefined'.
+-type child_id() :: term().
+-type mfargs() :: {M :: module(), F :: atom(), A :: [term()] | undefined}.
-type modules() :: [module()] | 'dynamic'.
-type restart() :: 'permanent' | 'transient' | 'temporary'.
-type shutdown() :: 'brutal_kill' | timeout().
-type worker() :: 'worker' | 'supervisor'.
--type sup_name() :: {'local', atom()} | {'global', atom()}.
--type sup_ref() :: atom() | {atom(), atom()} | {'global', atom()} | pid().
--type child_spec() :: {term(),mfargs(),restart(),shutdown(),worker(),modules()}.
+-type sup_name() :: {'local', Name :: atom()} | {'global', Name :: atom()}.
+-type sup_ref() :: (Name :: atom())
+ | {Name :: atom(), Node :: node()}
+ | {'global', Name :: atom()}
+ | pid().
+-type child_spec() :: {Id :: child_id(),
+ StartFunc :: mfargs(),
+ Restart :: restart(),
+ Shutdown :: shutdown(),
+ Type :: worker(),
+ Modules :: modules()}.
-type strategy() :: 'one_for_all' | 'one_for_one'
| 'rest_for_one' | 'simple_one_for_one'.
@@ -55,14 +64,14 @@
%%--------------------------------------------------------------------------
-record(child, {% pid is undefined when child is not running
- pid = undefined :: child_id(),
+ pid = undefined :: child(),
name,
mfargs :: mfargs(),
restart_type :: restart(),
shutdown :: shutdown(),
child_type :: worker(),
modules = [] :: modules()}).
--type child() :: #child{}.
+-type child_rec() :: #child{}.
-define(DICT, dict).
-define(SETS, sets).
@@ -70,7 +79,7 @@
-record(state, {name,
strategy :: strategy(),
- children = [] :: [child()],
+ children = [] :: [child_rec()],
dynamics :: ?DICT() | ?SET(),
intensity :: non_neg_integer(),
period :: pos_integer(),
@@ -99,11 +108,16 @@ behaviour_info(_Other) ->
-type startlink_err() :: {'already_started', pid()} | 'shutdown' | term().
-type startlink_ret() :: {'ok', pid()} | 'ignore' | {'error', startlink_err()}.
--spec start_link(module(), term()) -> startlink_ret().
+-spec start_link(Module, Args) -> startlink_ret() when
+ Module :: module(),
+ Args :: term().
start_link(Mod, Args) ->
gen_server:start_link(supervisor, {self, Mod, Args}, []).
--spec start_link(sup_name(), module(), term()) -> startlink_ret().
+-spec start_link(SupName, Module, Args) -> startlink_ret() when
+ SupName :: sup_name(),
+ Module :: module(),
+ Args :: term().
start_link(SupName, Mod, Args) ->
gen_server:start_link(SupName, supervisor, {SupName, Mod, Args}, []).
@@ -111,24 +125,33 @@ start_link(SupName, Mod, Args) ->
%%% Interface functions.
%%% ---------------------------------------------------
--type info() :: term().
-type startchild_err() :: 'already_present'
- | {'already_started', child_id()} | term().
--type startchild_ret() :: {'ok', child_id()} | {'ok', child_id(), info()}
+ | {'already_started', Child :: child()} | term().
+-type startchild_ret() :: {'ok', Child :: child()}
+ | {'ok', Child :: child(), Info :: term()}
| {'error', startchild_err()}.
--spec start_child(sup_ref(), child_spec() | [term()]) -> startchild_ret().
+-spec start_child(SupRef, ChildSpec) -> startchild_ret() when
+ SupRef :: sup_ref(),
+ ChildSpec :: child_spec() | (List :: [term()]).
start_child(Supervisor, ChildSpec) ->
call(Supervisor, {start_child, ChildSpec}).
--type restart_err() :: 'running' | 'not_found' | 'simple_one_for_one' | term().
--spec restart_child(sup_ref(), term()) ->
- {'ok', child_id()} | {'ok', child_id(), info()} | {'error', restart_err()}.
+-spec restart_child(SupRef, Id) -> Result when
+ SupRef :: sup_ref(),
+ Id :: child_id(),
+ Result :: {'ok', Child :: child()}
+ | {'ok', Child :: child(), Info :: term()}
+ | {'error', Error},
+ Error :: 'running' | 'not_found' | 'simple_one_for_one' | term().
restart_child(Supervisor, Name) ->
call(Supervisor, {restart_child, Name}).
--type del_err() :: 'running' | 'not_found' | 'simple_one_for_one'.
--spec delete_child(sup_ref(), term()) -> 'ok' | {'error', del_err()}.
+-spec delete_child(SupRef, Id) -> Result when
+ SupRef :: sup_ref(),
+ Id :: child_id(),
+ Result :: 'ok' | {'error', Error},
+ Error :: 'running' | 'not_found' | 'simple_one_for_one'.
delete_child(Supervisor, Name) ->
call(Supervisor, {delete_child, Name}).
@@ -139,22 +162,39 @@ delete_child(Supervisor, Name) ->
%% way (maybe killed).
%%-----------------------------------------------------------------
--type term_err() :: 'not_found' | 'simple_one_for_one'.
--spec terminate_child(sup_ref(), pid() | term()) -> 'ok' | {'error', term_err()}.
+-spec terminate_child(SupRef, Id) -> Result when
+ SupRef :: sup_ref(),
+ Id :: pid() | child_id(),
+ Result :: 'ok' | {'error', Error},
+ Error :: 'not_found' | 'simple_one_for_one'.
terminate_child(Supervisor, Name) ->
call(Supervisor, {terminate_child, Name}).
--spec which_children(sup_ref()) -> [{term(), child_id(), worker(), modules()}].
+-spec which_children(SupRef) -> [{Id,Child,Type,Modules}] when
+ SupRef :: sup_ref(),
+ Id :: child_id() | undefined,
+ Child :: child(),
+ Type :: worker(),
+ Modules :: modules().
which_children(Supervisor) ->
call(Supervisor, which_children).
+-spec count_children(SupRef) -> PropListOfCounts when
+ SupRef :: sup_ref(),
+ PropListOfCounts :: [Count],
+ Count :: {specs, ChildSpecCount :: non_neg_integer()}
+ | {active, ActiveProcessCount :: non_neg_integer()}
+ | {supervisors, ChildSupervisorCount :: non_neg_integer()}
+ |{workers, ChildWorkerCount :: non_neg_integer()}.
count_children(Supervisor) ->
call(Supervisor, count_children).
call(Supervisor, Req) ->
gen_server:call(Supervisor, Req, infinity).
--spec check_childspecs([child_spec()]) -> 'ok' | {'error', term()}.
+-spec check_childspecs(ChildSpecs) -> Result when
+ ChildSpecs :: [child_spec()],
+ Result :: 'ok' | {'error', Error :: term()}.
check_childspecs(ChildSpecs) when is_list(ChildSpecs) ->
case check_startspec(ChildSpecs) of
{ok, _} -> ok;
@@ -222,12 +262,12 @@ init_dynamic(_State, StartSpec) ->
%%-----------------------------------------------------------------
%% Func: start_children/2
-%% Args: Children = [child()] in start order
+%% Args: Children = [child_rec()] in start order
%% SupName = {local, atom()} | {global, atom()} | {pid(), Mod}
%% Purpose: Start all children. The new list contains #child's
%% with pids.
%% Returns: {ok, NChildren} | {error, NChildren}
-%% NChildren = [child()] in termination order (reversed
+%% NChildren = [child_rec()] in termination order (reversed
%% start order)
%%-----------------------------------------------------------------
start_children(Children, SupName) -> start_children(Children, [], SupName).
@@ -687,9 +727,9 @@ restart(one_for_all, Child, State) ->
%%-----------------------------------------------------------------
%% Func: terminate_children/2
-%% Args: Children = [child()] in termination order
+%% Args: Children = [child_rec()] in termination order
%% SupName = {local, atom()} | {global, atom()} | {pid(),Mod}
-%% Returns: NChildren = [child()] in
+%% Returns: NChildren = [child_rec()] in
%% startup order (reversed termination order)
%%-----------------------------------------------------------------
terminate_children(Children, SupName) ->
@@ -958,7 +998,7 @@ supname(N, _) -> N.
%%% Shutdown = integer() | infinity | brutal_kill
%%% ChildType = supervisor | worker
%%% Modules = [atom()] | dynamic
-%%% Returns: {ok, [child()]} | Error
+%%% Returns: {ok, [child_rec()]} | Error
%%% ------------------------------------------------------
check_startspec(Children) -> check_startspec(Children, []).
diff --git a/lib/stdlib/src/supervisor_bridge.erl b/lib/stdlib/src/supervisor_bridge.erl
index 3d2bd2c9a5..555cb5a66f 100644
--- a/lib/stdlib/src/supervisor_bridge.erl
+++ b/lib/stdlib/src/supervisor_bridge.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -49,9 +49,25 @@ behaviour_info(_Other) ->
%%%-----------------------------------------------------------------
-record(state, {mod, pid, child_state, name}).
+-spec start_link(Module, Args) -> Result when
+ Module :: module(),
+ Args :: term(),
+ Result :: {ok, Pid} | ignore | {error, Error},
+ Error :: {already_started, Pid} | term(),
+ Pid :: pid().
+
start_link(Mod, StartArgs) ->
gen_server:start_link(supervisor_bridge, [Mod, StartArgs, self], []).
+-spec start_link(SupBridgeName, Module, Args) -> Result when
+ SupBridgeName :: {local, Name} | {global, Name},
+ Name :: atom(),
+ Module :: module(),
+ Args :: term(),
+ Result :: {ok, Pid} | ignore | {error, Error},
+ Error :: {already_started, Pid} | term(),
+ Pid :: pid().
+
start_link(Name, Mod, StartArgs) ->
gen_server:start_link(Name, supervisor_bridge, [Mod, StartArgs, Name], []).
diff --git a/lib/stdlib/src/sys.erl b/lib/stdlib/src/sys.erl
index 12209c16d7..8ab72c9b50 100644
--- a/lib/stdlib/src/sys.erl
+++ b/lib/stdlib/src/sys.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -33,22 +33,74 @@
%%-----------------------------------------------------------------
-type name() :: pid() | atom() | {'global', atom()}.
--type system_event() :: {'in', _Msg} | {'in', _Msg, _From} | {'out', _Msg, _To}.
+-type system_event() :: {'in', Msg :: _}
+ | {'in', Msg :: _, From :: _}
+ | {'out', Msg :: _, To :: _}
+ | term().
+-opaque dbg_opt() :: list().
+-type dbg_fun() :: fun((FuncState :: _,
+ Event :: system_event(),
+ ProcState :: _) -> 'done' | (NewFuncState :: _)).
%%-----------------------------------------------------------------
%% System messages
%%-----------------------------------------------------------------
+-spec suspend(Name) -> Void when
+ Name :: name(),
+ Void :: term().
suspend(Name) -> send_system_msg(Name, suspend).
+-spec suspend(Name, Timeout) -> Void when
+ Name :: name(),
+ Timeout :: timeout(),
+ Void :: term().
suspend(Name, Timeout) -> send_system_msg(Name, suspend, Timeout).
+-spec resume(Name) -> Void when
+ Name :: name(),
+ Void :: term().
resume(Name) -> send_system_msg(Name, resume).
+-spec resume(Name, Timeout) -> Void when
+ Name :: name(),
+ Timeout :: timeout(),
+ Void :: term().
resume(Name, Timeout) -> send_system_msg(Name, resume, Timeout).
+-spec get_status(Name) -> Status when
+ Name :: name(),
+ Status :: {status, Pid :: pid(), {module, Module :: module()}, [SItem]},
+ SItem :: (PDict :: [{Key :: term(), Value :: term()}])
+ | (SysState :: 'running' | 'suspended')
+ | (Parent :: pid())
+ | (Dbg :: dbg_opt())
+ | (Misc :: term()).
get_status(Name) -> send_system_msg(Name, get_status).
+-spec get_status(Name, Timeout) -> Status when
+ Name :: name(),
+ Timeout :: timeout(),
+ Status :: {status, Pid :: pid(), {module, Module :: module()}, [SItem]},
+ SItem :: (PDict :: [{Key :: term(), Value :: term()}])
+ | (SysState :: 'running' | 'suspended')
+ | (Parent :: pid())
+ | (Dbg :: dbg_opt())
+ | (Misc :: term()).
get_status(Name, Timeout) -> send_system_msg(Name, get_status, Timeout).
+-spec change_code(Name, Module, OldVsn, Extra) -> 'ok' | {error, Reason} when
+ Name :: name(),
+ Module :: module(),
+ OldVsn :: 'undefined' | term(),
+ Extra :: term(),
+ Reason :: term().
change_code(Name, Mod, Vsn, Extra) ->
send_system_msg(Name, {change_code, Mod, Vsn, Extra}).
+-spec change_code(Name, Module, OldVsn, Extra, Timeout) ->
+ 'ok' | {error, Reason} when
+ Name :: name(),
+ Module :: module(),
+ OldVsn :: 'undefined' | term(),
+ Extra :: term(),
+ Timeout :: timeout(),
+ Reason :: term().
change_code(Name, Mod, Vsn, Extra, Timeout) ->
send_system_msg(Name, {change_code, Mod, Vsn, Extra}, Timeout).
@@ -56,52 +108,116 @@ change_code(Name, Mod, Vsn, Extra, Timeout) ->
%% Debug commands
%%-----------------------------------------------------------------
--type log_flag() :: 'true' | {'true',pos_integer()} | 'false' | 'get' | 'print'.
-
--spec log(name(), log_flag()) -> 'ok' | {'ok', [system_event()]}.
+-spec log(Name, Flag) -> 'ok' | {'ok', [system_event()]} when
+ Name :: name(),
+ Flag :: 'true' |
+ {'true', N :: pos_integer()}
+ | 'false' | 'get' | 'print'.
log(Name, Flag) ->
send_system_msg(Name, {debug, {log, Flag}}).
--spec log(name(), log_flag(), timeout()) -> 'ok' | {'ok', [system_event()]}.
+-spec log(Name, Flag, Timeout) -> 'ok' | {'ok', [system_event()]} when
+ Name :: name(),
+ Flag :: 'true' |
+ {'true', N :: pos_integer()}
+ | 'false' | 'get' | 'print',
+ Timeout :: timeout().
log(Name, Flag, Timeout) ->
send_system_msg(Name, {debug, {log, Flag}}, Timeout).
--spec trace(name(), boolean()) -> 'ok'.
+-spec trace(Name, Flag) -> 'ok' when
+ Name :: name(),
+ Flag :: boolean().
trace(Name, Flag) ->
send_system_msg(Name, {debug, {trace, Flag}}).
--spec trace(name(), boolean(), timeout()) -> 'ok'.
+-spec trace(Name, Flag, Timeout) -> 'ok' when
+ Name :: name(),
+ Flag :: boolean(),
+ Timeout :: timeout().
trace(Name, Flag, Timeout) ->
send_system_msg(Name, {debug, {trace, Flag}}, Timeout).
--type l2f_fname() :: string() | 'false'.
-
--spec log_to_file(name(), l2f_fname()) -> 'ok' | {'error','open_file'}.
+-spec log_to_file(Name, Flag) -> 'ok' | {'error','open_file'} when
+ Name :: name(),
+ Flag :: (FileName :: string()) | 'false'.
log_to_file(Name, FileName) ->
send_system_msg(Name, {debug, {log_to_file, FileName}}).
--spec log_to_file(name(), l2f_fname(), timeout()) -> 'ok' | {'error','open_file'}.
+-spec log_to_file(Name, Flag, Timeout) -> 'ok' | {'error','open_file'} when
+ Name :: name(),
+ Flag :: (FileName :: string()) | 'false',
+ Timeout :: timeout().
log_to_file(Name, FileName, Timeout) ->
send_system_msg(Name, {debug, {log_to_file, FileName}}, Timeout).
+-spec statistics(Name, Flag) -> 'ok' | {'ok', Statistics} when
+ Name :: name(),
+ Flag :: 'true' | 'false' | 'get',
+ Statistics :: [StatisticsTuple],
+ StatisticsTuple :: {'start_time', DateTime1}
+ | {'current_time', DateTime2}
+ | {'reductions', non_neg_integer()}
+ | {'messages_in', non_neg_integer()}
+ | {'messages_out', non_neg_integer()},
+ DateTime1 :: file:date_time(),
+ DateTime2 :: file:date_time().
statistics(Name, Flag) ->
send_system_msg(Name, {debug, {statistics, Flag}}).
+
+-spec statistics(Name, Flag, Timeout) -> 'ok' | {'ok', Statistics} when
+ Name :: name(),
+ Flag :: 'true' | 'false' | 'get',
+ Statistics :: [StatisticsTuple],
+ StatisticsTuple :: {'start_time', DateTime1}
+ | {'current_time', DateTime2}
+ | {'reductions', non_neg_integer()}
+ | {'messages_in', non_neg_integer()}
+ | {'messages_out', non_neg_integer()},
+ DateTime1 :: file:date_time(),
+ DateTime2 :: file:date_time(),
+ Timeout :: timeout().
statistics(Name, Flag, Timeout) ->
send_system_msg(Name, {debug, {statistics, Flag}}, Timeout).
--spec no_debug(name()) -> 'ok'.
+-spec no_debug(Name) -> 'ok' when
+ Name :: name().
no_debug(Name) -> send_system_msg(Name, {debug, no_debug}).
--spec no_debug(name(), timeout()) -> 'ok'.
+-spec no_debug(Name, Timeout) -> 'ok' when
+ Name :: name(),
+ Timeout :: timeout().
no_debug(Name, Timeout) -> send_system_msg(Name, {debug, no_debug}, Timeout).
+-spec install(Name, FuncSpec) -> Void when
+ Name :: name(),
+ FuncSpec :: {Func, FuncState},
+ Func :: dbg_fun(),
+ FuncState :: term(),
+ Void :: term().
install(Name, {Func, FuncState}) ->
send_system_msg(Name, {debug, {install, {Func, FuncState}}}).
+-spec install(Name, FuncSpec, Timeout) -> Void when
+ Name :: name(),
+ FuncSpec :: {Func, FuncState},
+ Func :: dbg_fun(),
+ FuncState :: term(),
+ Timeout :: timeout(),
+ Void :: term().
install(Name, {Func, FuncState}, Timeout) ->
send_system_msg(Name, {debug, {install, {Func, FuncState}}}, Timeout).
+-spec remove(Name, Func) -> Void when
+ Name :: name(),
+ Func :: dbg_fun(),
+ Void :: term().
remove(Name, Func) ->
send_system_msg(Name, {debug, {remove, Func}}).
+-spec remove(Name, Func, Timeout) -> Void when
+ Name :: name(),
+ Func :: dbg_fun(),
+ Timeout :: timeout(),
+ Void :: term().
remove(Name, Func, Timeout) ->
send_system_msg(Name, {debug, {remove, Func}}, Timeout).
@@ -150,6 +266,14 @@ mfa(Name, Req, Timeout) ->
%% The Module must export system_continue/3, system_terminate/4
%% and format_status/2 for status information.
%%-----------------------------------------------------------------
+-spec handle_system_msg(Msg, From, Parent, Module, Debug, Misc) -> Void when
+ Msg :: term(),
+ From :: {pid(), Tag :: _},
+ Parent :: pid(),
+ Module :: module(),
+ Debug :: [dbg_opt()],
+ Misc :: term(),
+ Void :: term().
handle_system_msg(Msg, From, Parent, Module, Debug, Misc) ->
handle_system_msg(running, Msg, From, Parent, Module, Debug, Misc, false).
@@ -176,6 +300,11 @@ handle_system_msg(SysState, Msg, From, Parent, Mod, Debug, Misc, Hib) ->
%% Func is a formatting function, called as Func(Device, Event).
%% Returns: [debug_opts()]
%%-----------------------------------------------------------------
+-spec handle_debug(Debug, FormFunc, Extra, Event) -> [dbg_opt()] when
+ Debug :: [dbg_opt()],
+ FormFunc :: dbg_fun(),
+ Extra :: term(),
+ Event :: system_event().
handle_debug([{trace, true} | T], FormFunc, State, Event) ->
print_event({Event, State, FormFunc}),
[{trace, true} | handle_debug(T, FormFunc, State, Event)];
@@ -341,24 +470,36 @@ trim(N, LogData) ->
%% Debug structure manipulating functions
%%-----------------------------------------------------------------
install_debug(Item, Data, Debug) ->
- case get_debug(Item, Debug, undefined) of
+ case get_debug2(Item, Debug, undefined) of
undefined -> [{Item, Data} | Debug];
_ -> Debug
end.
remove_debug(Item, Debug) -> lists:keydelete(Item, 1, Debug).
+
+-spec get_debug(Item, Debug, Default) -> term() when
+ Item :: 'log' | 'statistics',
+ Debug :: [dbg_opt()],
+ Default :: term().
get_debug(Item, Debug, Default) ->
+ get_debug2(Item, Debug, Default).
+
+%% Workaround: accepts more Item types than get_debug/3.
+get_debug2(Item, Debug, Default) ->
case lists:keysearch(Item, 1, Debug) of
{value, {Item, Data}} -> Data;
_ -> Default
end.
+-spec print_log(Debug) -> Void when
+ Debug :: [dbg_opt()],
+ Void :: term().
print_log(Debug) ->
{_N, Logs} = get_debug(log, Debug, {0, []}),
lists:foreach(fun print_event/1,
lists:reverse(Logs)).
close_log_file(Debug) ->
- case get_debug(log_to_file, Debug, []) of
+ case get_debug2(log_to_file, Debug, []) of
[] ->
Debug;
Fd ->
@@ -375,6 +516,15 @@ close_log_file(Debug) ->
%% system messages.
%% Returns: [debug_opts()]
%%-----------------------------------------------------------------
+
+-spec debug_options(Options) -> [dbg_opt()] when
+ Options :: [Opt],
+ Opt :: 'trace' | 'log' | 'statistics' | {'log_to_file', FileName}
+ | {'install', FuncSpec},
+ FileName :: file:name(),
+ FuncSpec :: {Func, FuncState},
+ Func :: dbg_fun(),
+ FuncState :: term().
debug_options(Options) ->
debug_options(Options, []).
debug_options([trace | T], Debug) ->
diff --git a/lib/stdlib/src/timer.erl b/lib/stdlib/src/timer.erl
index b456c5d6c1..89fae05e4f 100644
--- a/lib/stdlib/src/timer.erl
+++ b/lib/stdlib/src/timer.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -22,7 +22,7 @@
send_after/3, send_after/2,
exit_after/3, exit_after/2, kill_after/2, kill_after/1,
apply_interval/4, send_interval/3, send_interval/2,
- cancel/1, sleep/1, tc/2, tc/3, now_diff/2,
+ cancel/1, sleep/1, tc/1, tc/2, tc/3, now_diff/2,
seconds/1, minutes/1, hours/1, hms/3]).
-export([start_link/0, start/0,
@@ -46,103 +46,189 @@
%%
-opaque tref() :: {integer(), reference()}.
-type time() :: non_neg_integer().
--type timestamp() :: {non_neg_integer(), non_neg_integer(), non_neg_integer()}.
%%
%% Interface functions
%%
--spec apply_after(time(), atom(), atom(), [term()]) -> {'ok', tref()} | {'error', term()}.
+-spec apply_after(Time, Module, Function, Arguments) ->
+ {'ok', TRef} | {'error', Reason} when
+ Time :: time(),
+ Module :: module(),
+ Function :: atom(),
+ Arguments :: [term()],
+ TRef :: tref(),
+ Reason :: term().
+
apply_after(Time, M, F, A) ->
req(apply_after, {Time, {M, F, A}}).
--spec send_after(time(), pid() | atom(), term()) -> {'ok', tref()} | {'error', term()}.
+-spec send_after(Time, Pid, Message) -> {'ok', TRef} | {'error', Reason} when
+ Time :: time(),
+ Pid :: pid() | (RegName :: atom()),
+ Message :: term(),
+ TRef :: tref(),
+ Reason :: term().
send_after(Time, Pid, Message) ->
req(apply_after, {Time, {?MODULE, send, [Pid, Message]}}).
--spec send_after(time(), term()) -> {'ok', tref()} | {'error', term()}.
+-spec send_after(Time, Message) -> {'ok', TRef} | {'error', Reason} when
+ Time :: time(),
+ Message :: term(),
+ TRef :: tref(),
+ Reason :: term().
send_after(Time, Message) ->
send_after(Time, self(), Message).
--spec exit_after(time(), pid() | atom(), term()) -> {'ok', tref()} | {'error', term()}.
+-spec exit_after(Time, Pid, Reason1) -> {'ok', TRef} | {'error', Reason2} when
+ Time :: time(),
+ Pid :: pid() | (RegName :: atom()),
+ TRef :: tref(),
+ Reason1 :: term(),
+ Reason2 :: term().
exit_after(Time, Pid, Reason) ->
req(apply_after, {Time, {erlang, exit, [Pid, Reason]}}).
--spec exit_after(time(), term()) -> {'ok', tref()} | {'error', term()}.
+-spec exit_after(Time, Reason1) -> {'ok', TRef} | {'error', Reason2} when
+ Time :: time(),
+ TRef :: tref(),
+ Reason1 :: term(),
+ Reason2 :: term().
exit_after(Time, Reason) ->
exit_after(Time, self(), Reason).
--spec kill_after(time(), pid() | atom()) -> {'ok', tref()} | {'error', term()}.
+-spec kill_after(Time, Pid) -> {'ok', TRef} | {'error', Reason2} when
+ Time :: time(),
+ Pid :: pid() | (RegName :: atom()),
+ TRef :: tref(),
+ Reason2 :: term().
kill_after(Time, Pid) ->
exit_after(Time, Pid, kill).
--spec kill_after(time()) -> {'ok', tref()} | {'error', term()}.
+-spec kill_after(Time) -> {'ok', TRef} | {'error', Reason2} when
+ Time :: time(),
+ TRef :: tref(),
+ Reason2 :: term().
kill_after(Time) ->
exit_after(Time, self(), kill).
--spec apply_interval(time(), atom(), atom(), [term()]) -> {'ok', tref()} | {'error', term()}.
+-spec apply_interval(Time, Module, Function, Arguments) ->
+ {'ok', TRef} | {'error', Reason} when
+ Time :: time(),
+ Module :: module(),
+ Function :: atom(),
+ Arguments :: [term()],
+ TRef :: tref(),
+ Reason :: term().
apply_interval(Time, M, F, A) ->
req(apply_interval, {Time, self(), {M, F, A}}).
--spec send_interval(time(), pid() | atom(), term()) -> {'ok', tref()} | {'error', term()}.
+-spec send_interval(Time, Pid, Message) ->
+ {'ok', TRef} | {'error', Reason} when
+ Time :: time(),
+ Pid :: pid() | (RegName :: atom()),
+ Message :: term(),
+ TRef :: tref(),
+ Reason :: term().
send_interval(Time, Pid, Message) ->
req(apply_interval, {Time, Pid, {?MODULE, send, [Pid, Message]}}).
--spec send_interval(time(), term()) -> {'ok', tref()} | {'error', term()}.
+-spec send_interval(Time, Message) -> {'ok', TRef} | {'error', Reason} when
+ Time :: time(),
+ Message :: term(),
+ TRef :: tref(),
+ Reason :: term().
send_interval(Time, Message) ->
send_interval(Time, self(), Message).
--spec cancel(tref()) -> {'ok', 'cancel'} | {'error', term()}.
+-spec cancel(TRef) -> {'ok', 'cancel'} | {'error', Reason} when
+ TRef :: tref(),
+ Reason :: term().
cancel(BRef) ->
req(cancel, BRef).
--spec sleep(timeout()) -> 'ok'.
+-spec sleep(Time) -> 'ok' when
+ Time :: timeout().
sleep(T) ->
receive
after T -> ok
end.
+%%
+%% Measure the execution time (in microseconds) for Fun().
+%%
+-spec tc(Fun) -> {Time, Value} when
+ Fun :: function(),
+ Time :: integer(),
+ Value :: term().
+tc(F) ->
+ Before = os:timestamp(),
+ Val = F(),
+ After = os:timestamp(),
+ {now_diff(After, Before), Val}.
%%
%% Measure the execution time (in microseconds) for Fun(Args).
%%
--spec tc(function(), [_]) -> {time(), term()}.
+-spec tc(Fun, Arguments) -> {Time, Value} when
+ Fun :: function(),
+ Arguments :: [term()],
+ Time :: integer(),
+ Value :: term().
tc(F, A) ->
- Before = erlang:now(),
- Val = (catch apply(F, A)),
- After = erlang:now(),
+ Before = os:timestamp(),
+ Val = apply(F, A),
+ After = os:timestamp(),
{now_diff(After, Before), Val}.
%%
%% Measure the execution time (in microseconds) for an MFA.
%%
--spec tc(atom(), atom(), [term()]) -> {time(), term()}.
+-spec tc(Module, Function, Arguments) -> {Time, Value} when
+ Module :: module(),
+ Function :: atom(),
+ Arguments :: [term()],
+ Time :: integer(),
+ Value :: term().
tc(M, F, A) ->
- Before = erlang:now(),
- Val = (catch apply(M, F, A)),
- After = erlang:now(),
+ Before = os:timestamp(),
+ Val = apply(M, F, A),
+ After = os:timestamp(),
{now_diff(After, Before), Val}.
%%
%% Calculate the time difference (in microseconds) of two
%% erlang:now() timestamps, T2-T1.
%%
--spec now_diff(timestamp(), timestamp()) -> integer().
+-spec now_diff(T1, T2) -> Tdiff when
+ T1 :: calendar:t_now(),
+ T2 :: calendar:t_now(),
+ Tdiff :: integer().
now_diff({A2, B2, C2}, {A1, B1, C1}) ->
((A2-A1)*1000000 + B2-B1)*1000000 + C2-C1.
%%
%% Convert seconds, minutes etc. to milliseconds.
%%
--spec seconds(non_neg_integer()) -> non_neg_integer().
+-spec seconds(Seconds) -> MilliSeconds when
+ Seconds :: non_neg_integer(),
+ MilliSeconds :: non_neg_integer().
seconds(Seconds) ->
1000*Seconds.
--spec minutes(non_neg_integer()) -> non_neg_integer().
+-spec minutes(Minutes) -> MilliSeconds when
+ Minutes :: non_neg_integer(),
+ MilliSeconds :: non_neg_integer().
minutes(Minutes) ->
1000*60*Minutes.
--spec hours(non_neg_integer()) -> non_neg_integer().
+-spec hours(Hours) -> MilliSeconds when
+ Hours :: non_neg_integer(),
+ MilliSeconds :: non_neg_integer().
hours(Hours) ->
1000*60*60*Hours.
--spec hms(non_neg_integer(), non_neg_integer(), non_neg_integer()) -> non_neg_integer().
+-spec hms(Hours, Minutes, Seconds) -> MilliSeconds when
+ Hours :: non_neg_integer(),
+ Minutes :: non_neg_integer(),
+ Seconds :: non_neg_integer(),
+ MilliSeconds :: non_neg_integer().
hms(H, M, S) ->
hours(H) + minutes(M) + seconds(S).
diff --git a/lib/stdlib/src/unicode.erl b/lib/stdlib/src/unicode.erl
index 12bc60623d..a5d9965ca2 100644
--- a/lib/stdlib/src/unicode.erl
+++ b/lib/stdlib/src/unicode.erl
@@ -30,12 +30,34 @@
characters_to_binary/3,
bom_to_encoding/1, encoding_to_bom/1]).
--export_type([encoding/0]).
+-export_type([chardata/0, charlist/0, encoding/0, external_chardata/0,
+ external_charlist/0, latin1_chardata/0,
+ latin1_charlist/0, unicode_binary/0, unicode_char/0]).
-type encoding() :: 'latin1' | 'unicode' | 'utf8'
| 'utf16' | {'utf16', endian()}
| 'utf32' | {'utf32', endian()}.
-type endian() :: 'big' | 'little'.
+-type unicode_binary() :: binary().
+-type unicode_char() :: non_neg_integer().
+-type charlist() :: [unicode_char() | unicode_binary() | charlist()].
+-type chardata() :: charlist() | unicode_binary().
+-type external_unicode_binary() :: binary().
+-type external_chardata() :: external_charlist() | external_unicode_binary().
+-type external_charlist() :: [unicode_char() | external_unicode_binary()
+ | external_charlist()].
+-type latin1_binary() :: binary().
+-type latin1_char() :: byte().
+-type latin1_chardata() :: latin1_charlist() | latin1_binary().
+-type latin1_charlist() :: [latin1_char() | latin1_binary()
+ | latin1_charlist()].
+
+-spec characters_to_list(Data) -> Result when
+ Data :: latin1_chardata() | chardata() | external_chardata(),
+ Result :: list()
+ | {error, list(), RestData}
+ | {incomplete, list(), binary()},
+ RestData :: latin1_chardata() | chardata() | external_chardata().
characters_to_list(ML) ->
unicode:characters_to_list(ML,unicode).
@@ -69,6 +91,13 @@ do_characters_to_list(ML, Encoding) ->
end.
+-spec characters_to_binary(Data) -> Result when
+ Data :: latin1_chardata() | chardata() | external_chardata(),
+ Result :: binary()
+ | {error, binary(), RestData}
+ | {incomplete, binary(), binary()},
+ RestData :: latin1_chardata() | chardata() | external_chardata().
+
characters_to_binary(ML) ->
try
unicode:characters_to_binary(ML,unicode)
@@ -104,6 +133,15 @@ characters_to_binary_int(ML,InEncoding) ->
erlang:raise(error,TheError,[{Mod,characters_to_binary,L}|Rest])
end.
+-spec characters_to_binary(Data, InEncoding, OutEncoding) -> Result when
+ Data :: latin1_chardata() | chardata() | external_chardata(),
+ InEncoding :: encoding(),
+ OutEncoding :: encoding(),
+ Result :: binary()
+ | {error, binary(), RestData}
+ | {incomplete, binary(), binary()},
+ RestData :: latin1_chardata() | chardata() | external_chardata().
+
characters_to_binary(ML, latin1, latin1) when is_binary(ML) ->
ML;
characters_to_binary(ML, latin1, Uni) when is_binary(ML) and ((Uni =:= utf8) or (Uni =:= unicode)) ->
@@ -215,6 +253,13 @@ characters_to_binary_int(ML, InEncoding, OutEncoding) ->
Res
end.
+-spec bom_to_encoding(Bin) -> {Encoding, Length} when
+ Bin :: binary(),
+ Encoding :: 'latin1' | 'utf8'
+ | {'utf16', endian()}
+ | {'utf32', endian()},
+ Length :: non_neg_integer().
+
bom_to_encoding(<<239,187,191,_/binary>>) ->
{utf8,3};
bom_to_encoding(<<0,0,254,255,_/binary>>) ->
@@ -228,6 +273,10 @@ bom_to_encoding(<<255,254,_/binary>>) ->
bom_to_encoding(Bin) when is_binary(Bin) ->
{latin1,0}.
+-spec encoding_to_bom(InEncoding) -> Bin when
+ Bin :: binary(),
+ InEncoding :: encoding().
+
encoding_to_bom(unicode) ->
<<239,187,191>>;
encoding_to_bom(utf8) ->
diff --git a/lib/stdlib/src/win32reg.erl b/lib/stdlib/src/win32reg.erl
index ee0d17bc94..598e77ffdc 100644
--- a/lib/stdlib/src/win32reg.erl
+++ b/lib/stdlib/src/win32reg.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -52,14 +52,17 @@
-define(reg_dword, 4).
%% Basic types internal to this file.
--type open_mode() :: 'read' | 'write'.
--type reg_handle() :: {'win32reg',port()}.
+-opaque reg_handle() :: {'win32reg',port()}.
-type name() :: string() | 'default'.
-type value() :: string() | integer() | binary().
%%% Exported functions.
--spec open([open_mode()]) -> {'ok', reg_handle()} | {'error', 'enotsup'}.
+-spec open(OpenModeList) -> ReturnValue when
+ OpenModeList :: [OpenMode],
+ OpenMode :: 'read' | 'write',
+ ReturnValue :: {'ok', RegHandle} | {'error', ErrorId :: 'enotsup'},
+ RegHandle :: reg_handle().
open(Modes) ->
case os:type() of
@@ -75,14 +78,17 @@ open(Modes) ->
{error, enotsup}
end.
--spec close(reg_handle()) -> 'ok'.
+-spec close(RegHandle) -> 'ok' when
+ RegHandle :: reg_handle().
close({win32reg, Reg}) when is_port(Reg) ->
unlink(Reg),
exit(Reg, die),
ok.
--spec current_key(reg_handle()) -> {'ok', string()}.
+-spec current_key(RegHandle) -> ReturnValue when
+ RegHandle :: reg_handle(),
+ ReturnValue :: {'ok', string()}.
current_key({win32reg, Reg}) when is_port(Reg) ->
Cmd = [?cmd_get_current],
@@ -94,12 +100,18 @@ current_key({win32reg, Reg}) when is_port(Reg) ->
_ -> Root ++ [$\\|Name]
end}.
--spec change_key(reg_handle(), string()) -> 'ok' | {'error', atom()}.
+-spec change_key(RegHandle, Key) -> ReturnValue when
+ RegHandle :: reg_handle(),
+ Key :: string(),
+ ReturnValue :: 'ok' | {'error', ErrorId :: atom()}.
change_key({win32reg, Reg}, Key) when is_port(Reg) ->
change_key(Reg, ?cmd_open_key, Key).
--spec change_key_create(reg_handle(), string()) -> 'ok' | {'error', atom()}.
+-spec change_key_create(RegHandle, Key) -> ReturnValue when
+ RegHandle :: reg_handle(),
+ Key :: string(),
+ ReturnValue :: 'ok' | {'error', ErrorId :: atom()}.
change_key_create({win32reg, Reg}, Key) when is_port(Reg) ->
change_key(Reg, ?cmd_create_key, Key).
@@ -113,21 +125,30 @@ change_key(Reg, Cmd, Key) ->
{error, Reason}
end.
--spec sub_keys(reg_handle()) -> {'ok', [string()]} | {'error', atom()}.
+-spec sub_keys(RegHandle) -> ReturnValue when
+ RegHandle :: reg_handle(),
+ ReturnValue :: {'ok', [SubKey]} | {'error', ErrorId :: atom()},
+ SubKey :: string().
sub_keys({win32reg, Reg}) when is_port(Reg) ->
Cmd = [?cmd_get_all_subkeys],
Reg ! {self(), {command, Cmd}},
collect_keys(Reg, []).
--spec delete_key(reg_handle()) -> 'ok' | {'error', atom()}.
+-spec delete_key(RegHandle) -> ReturnValue when
+ RegHandle :: reg_handle(),
+ ReturnValue :: 'ok' | {'error', ErrorId :: atom()}.
delete_key({win32reg, Reg}) when is_port(Reg) ->
Cmd = [?cmd_delete_key],
Reg ! {self(), {command, Cmd}},
get_result(Reg).
--spec set_value(reg_handle(), name(), value()) -> 'ok' | {'error', atom()}.
+-spec set_value(RegHandle, Name, Value) -> ReturnValue when
+ RegHandle :: reg_handle(),
+ Name :: name(),
+ Value :: value(),
+ ReturnValue :: 'ok' | {'error', ErrorId :: atom()}.
set_value({win32reg, Reg}, Name0, Value) when is_port(Reg) ->
Name =
@@ -140,7 +161,10 @@ set_value({win32reg, Reg}, Name0, Value) when is_port(Reg) ->
Reg ! {self(), {command, Cmd}},
get_result(Reg).
--spec value(reg_handle(), name()) -> {'ok', value()} | {'error', atom()}.
+-spec value(RegHandle, Name) -> ReturnValue when
+ RegHandle :: reg_handle(),
+ Name :: name(),
+ ReturnValue :: {'ok', Value :: value()} | {'error', ErrorId :: atom()}.
value({win32reg, Reg}, Name) when is_port(Reg) ->
Cmd = [?cmd_get_value, Name, 0],
@@ -152,14 +176,20 @@ value({win32reg, Reg}, Name) when is_port(Reg) ->
{error, Reason}
end.
--spec values(reg_handle()) -> {'ok', [{name(), value()}]} | {'error', atom()}.
+-spec values(RegHandle) -> ReturnValue when
+ RegHandle :: reg_handle(),
+ ReturnValue :: {'ok', [ValuePair]} | {'error', ErrorId :: atom()},
+ ValuePair :: {Name :: name(), Value :: value()}.
values({win32reg, Reg}) when is_port(Reg) ->
Cmd = [?cmd_get_all_values],
Reg ! {self(), {command, Cmd}},
collect_values(Reg, []).
--spec delete_value(reg_handle(), name()) -> 'ok' | {'error', atom()}.
+-spec delete_value(RegHandle, Name) -> ReturnValue when
+ RegHandle :: reg_handle(),
+ Name :: name(),
+ ReturnValue :: 'ok' | {'error', ErrorId :: atom()}.
delete_value({win32reg, Reg}, Name0) when is_port(Reg) ->
Name =
@@ -171,7 +201,9 @@ delete_value({win32reg, Reg}, Name0) when is_port(Reg) ->
Reg ! {self(), {command, Cmd}},
get_result(Reg).
--spec expand(string()) -> string().
+-spec expand(String) -> ExpandedString when
+ String :: string(),
+ ExpandedString :: string().
expand(Value) ->
expand(Value, [], []).
@@ -195,7 +227,9 @@ expand([C|Rest], Env, Result) ->
expand([], [], Result) ->
lists:reverse(Result).
--spec format_error(atom()) -> string().
+-spec format_error(ErrorId) -> ErrorString when
+ ErrorId :: atom(),
+ ErrorString :: string().
format_error(ErrorId) ->
erl_posix_msg:message(ErrorId).
@@ -203,7 +237,7 @@ format_error(ErrorId) ->
%%% Implementation.
-spec collect_values(port(), [{name(), value()}]) ->
- {'ok', [{name(), value()}]} | {'error', atom()}.
+ {'ok', [{name(), value()}]} | {'error', ErrorId :: atom()}.
collect_values(P, Result) ->
case get_result(P) of
@@ -215,7 +249,7 @@ collect_values(P, Result) ->
{error, Reason}
end.
--spec collect_keys(port(), string()) -> {'ok', [string()]} | {'error', atom()}.
+-spec collect_keys(port(), string()) -> {'ok', [string()]} | {'error', ErrorId :: atom()}.
collect_keys(P, Result) ->
case get_result(P) of
diff --git a/lib/stdlib/src/zip.erl b/lib/stdlib/src/zip.erl
index d41aeefa59..524d709431 100644
--- a/lib/stdlib/src/zip.erl
+++ b/lib/stdlib/src/zip.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -203,6 +203,9 @@
zip_comment_length}).
+-type zip_file() :: #zip_file{}.
+-type zip_comment() :: #zip_comment{}.
+
%% Open a zip archive with options
%%
@@ -323,8 +326,33 @@ openzip_close(_) ->
%% Accepted options:
%% verbose, cooked, file_list, keep_old_files, file_filter, memory
+-spec(unzip(Archive) -> RetValue when
+ Archive :: file:name() | binary(),
+ RetValue :: {ok, FileList}
+ | {ok, FileBinList}
+ | {error, Reason :: term()}
+ | {error, {Name :: file:name(), Reason :: term()}},
+ FileList :: [file:name()],
+ FileBinList :: [{file:name(),binary()}]).
+
unzip(F) -> unzip(F, []).
+-spec(unzip(Archive, Options) -> RetValue when
+ Archive :: file:name() | binary(),
+ Options :: [Option],
+ Option :: {file_list, FileList}
+ | keep_old_files | verbose | memory |
+ {file_filter, FileFilter} | {cwd, CWD},
+ FileList :: [file:name()],
+ FileBinList :: [{file:name(),binary()}],
+ FileFilter :: fun((ZipFile) -> boolean()),
+ CWD :: string(),
+ ZipFile :: zip_file(),
+ RetValue :: {ok, FileList}
+ | {ok, FileBinList}
+ | {error, Reason :: term()}
+ | {error, {Name :: file:name(), Reason :: term()}}).
+
unzip(F, Options) ->
case ?CATCH do_unzip(F, Options) of
{ok, R} -> {ok, R};
@@ -345,6 +373,18 @@ do_unzip(F, Options) ->
{ok, Files}.
%% Iterate over all files in a zip archive
+-spec(foldl(Fun, Acc0, Archive) -> {ok, Acc1} | {error, Reason} when
+ Fun :: fun((FileInArchive, GetInfo, GetBin, AccIn) -> AccOut),
+ FileInArchive :: file:name(),
+ GetInfo :: fun(() -> file:file_info()),
+ GetBin :: fun(() -> binary()),
+ Acc0 :: term(),
+ Acc1 :: term(),
+ AccIn :: term(),
+ AccOut :: term(),
+ Archive :: file:name() | {file:name(), binary()},
+ Reason :: term()).
+
foldl(Fun, Acc0, Archive) when is_function(Fun, 4) ->
ZipFun =
fun({Name, GetInfo, GetBin}, A) ->
@@ -368,8 +408,33 @@ foldl(_,_, _) ->
%% Accepted options:
%% verbose, cooked, memory, comment
+-spec(zip(Name, FileList) -> RetValue when
+ Name :: file:name(),
+ FileList :: [FileSpec],
+ FileSpec :: file:name() | {file:name(), binary()}
+ | {file:name(), binary(), file:file_info()},
+ RetValue :: {ok, FileName :: file:name()}
+ | {ok, {FileName :: file:name(), binary()}}
+ | {error, Reason :: term()}).
+
zip(F, Files) -> zip(F, Files, []).
+-spec(zip(Name, FileList, Options) -> RetValue when
+ Name :: file:name(),
+ FileList :: [FileSpec],
+ FileSpec :: file:name() | {file:name(), binary()}
+ | {file:name(), binary(), file:file_info()},
+ Options :: [Option],
+ Option :: memory | cooked | verbose | {comment, Comment}
+ | {cwd, CWD} | {compress, What} | {uncompress, What},
+ What :: all | [Extension] | {add, [Extension]} | {del, [Extension]},
+ Extension :: string(),
+ Comment :: string(),
+ CWD :: string(),
+ RetValue :: {ok, FileName :: file:name()}
+ | {ok, {FileName :: file:name(), binary()}}
+ | {error, Reason :: term()}).
+
zip(F, Files, Options) ->
case ?CATCH do_zip(F, Files, Options) of
{ok, R} -> {ok, R};
@@ -392,8 +457,20 @@ do_zip(F, Files, Options) ->
%% Accepted options:
%% cooked, file_filter, file_output (latter 2 undocumented)
+-spec(list_dir(Archive) -> RetValue when
+ Archive :: file:name() | binary(),
+ RetValue :: {ok, CommentAndFiles} | {error, Reason :: term()},
+ CommentAndFiles :: [zip_comment() | zip_file()]).
+
list_dir(F) -> list_dir(F, []).
+-spec(list_dir(Archive, Options) -> RetValue when
+ Archive :: file:name() | binary(),
+ RetValue :: {ok, CommentAndFiles} | {error, Reason :: term()},
+ CommentAndFiles :: [zip_comment() | zip_file()],
+ Options :: [Option],
+ Option :: cooked).
+
list_dir(F, Options) ->
case ?CATCH do_list_dir(F, Options) of
{ok, R} -> {ok, R};
@@ -411,6 +488,10 @@ do_list_dir(F, Options) ->
%% Print zip directory in short form
+-spec(t(Archive) -> ok when
+ Archive :: file:name() | binary | ZipHandle,
+ ZipHandle :: pid()).
+
t(F) when is_pid(F) -> zip_t(F);
t(F) when is_record(F, openzip) -> openzip_t(F);
t(F) -> t(F, fun raw_short_print_info_etc/5).
@@ -431,6 +512,10 @@ do_t(F, RawPrint) ->
%% Print zip directory in long form (like ls -l)
+-spec(tt(Archive) -> ok when
+ Archive :: file:name() | binary | ZipHandle,
+ ZipHandle :: pid()).
+
tt(F) when is_pid(F) -> zip_tt(F);
tt(F) when is_record(F, openzip) -> openzip_tt(F);
tt(F) -> t(F, fun raw_long_print_info_etc/5).
@@ -605,11 +690,78 @@ get_list_dir_options(F, Options) ->
get_list_dir_opt(Options, Opts).
%% aliases for erl_tar compatibility
+-spec(table(Archive) -> RetValue when
+ Archive :: file:name() | binary(),
+ RetValue :: {ok, CommentAndFiles} | {error, Reason :: term()},
+ CommentAndFiles :: [zip_comment() | zip_file()]).
+
table(F) -> list_dir(F).
+
+-spec(table(Archive, Options) -> RetValue when
+ Archive :: file:name() | binary(),
+ RetValue :: {ok, CommentAndFiles} | {error, Reason :: term()},
+ CommentAndFiles :: [zip_comment() | zip_file()],
+
+ Options :: [Option],
+ Option :: cooked).
+
table(F, O) -> list_dir(F, O).
+
+-spec(create(Name, FileList) -> RetValue when
+ Name :: file:name(),
+ FileList :: [FileSpec],
+ FileSpec :: file:name() | {file:name(), binary()}
+ | {file:name(), binary(), file:file_info()},
+ RetValue :: {ok, FileName :: file:name()}
+ | {ok, {FileName :: file:name(), binary()}}
+ | {error, Reason :: term()}).
+
create(F, Fs) -> zip(F, Fs).
+
+-spec(create(Name, FileList, Options) -> RetValue when
+ Name :: file:name(),
+ FileList :: [FileSpec],
+ FileSpec :: file:name() | {file:name(), binary()}
+ | {file:name(), binary(), file:file_info()},
+ Options :: [Option],
+ Option :: memory | cooked | verbose | {comment, Comment}
+ | {cwd, CWD} | {compress, What} | {uncompress, What},
+ What :: all | [Extension] | {add, [Extension]} | {del, [Extension]},
+ Extension :: string(),
+ Comment :: string(),
+ CWD :: string(),
+ RetValue :: {ok, FileName :: file:name()}
+ | {ok, {FileName :: file:name(), binary()}}
+ | {error, Reason :: term()}).
create(F, Fs, O) -> zip(F, Fs, O).
+
+-spec(extract(Archive) -> RetValue when
+ Archive :: file:name() | binary(),
+ RetValue :: {ok, FileList}
+ | {ok, FileBinList}
+ | {error, Reason :: term()}
+ | {error, {Name :: file:name(), Reason :: term()}},
+ FileList :: [file:name()],
+ FileBinList :: [{file:name(),binary()}]).
+
extract(F) -> unzip(F).
+
+-spec(extract(Archive, Options) -> RetValue when
+ Archive :: file:name() | binary(),
+ Options :: [Option],
+ Option :: {file_list, FileList}
+ | keep_old_files | verbose | memory |
+ {file_filter, FileFilter} | {cwd, CWD},
+ FileList :: [file:name()],
+ FileBinList :: [{file:name(),binary()}],
+ FileFilter :: fun((ZipFile) -> boolean()),
+ CWD :: string(),
+ ZipFile :: zip_file(),
+ RetValue :: {ok, FileList}
+ | {ok, FileBinList}
+ | {error, Reason :: term()}
+ | {error, {Name :: file:name(), Reason :: term()}}).
+
extract(F, O) -> unzip(F, O).
@@ -990,21 +1142,52 @@ server_loop(OpenZip) ->
{error, bad_msg}
end.
+-spec(zip_open(Archive) -> {ok, ZipHandle} | {error, Reason} when
+ Archive :: file:name() | binary(),
+ ZipHandle :: pid(),
+ Reason :: term()).
+
zip_open(Archive) -> zip_open(Archive, []).
+-spec(zip_open(Archive, Options) -> {ok, ZipHandle} | {error, Reason} when
+ Archive :: file:name() | binary(),
+ ZipHandle :: pid(),
+ Options :: [Option],
+ Option :: cooked | memory | {cwd, CWD :: string()},
+ Reason :: term()).
+
zip_open(Archive, Options) ->
Pid = spawn(fun() -> server_loop(not_open) end),
request(self(), Pid, {open, Archive, Options}).
+-spec(zip_get(ZipHandle) -> {ok, [Result]} | {error, Reason} when
+ ZipHandle :: pid(),
+ Result :: file:name() | {file:name(), binary()},
+ Reason :: term()).
+
zip_get(Pid) when is_pid(Pid) ->
request(self(), Pid, get).
+-spec(zip_close(ZipHandle) -> ok | {error, einval} when
+ ZipHandle :: pid()).
+
zip_close(Pid) when is_pid(Pid) ->
request(self(), Pid, close).
+-spec(zip_get(FileName, ZipHandle) -> {ok, [Result]} | {error, Reason} when
+ FileName :: file:name(),
+ ZipHandle :: pid(),
+ Result :: file:name() | {file:name(), binary()},
+ Reason :: term()).
+
zip_get(FileName, Pid) when is_pid(Pid) ->
request(self(), Pid, {get, FileName}).
+-spec(zip_list_dir(ZipHandle) -> Result | {error, Reason} when
+ Result :: [zip_comment() | zip_file()],
+ ZipHandle :: pid(),
+ Reason :: term()).
+
zip_list_dir(Pid) when is_pid(Pid) ->
request(self(), Pid, list_dir).
diff --git a/lib/stdlib/test/erl_eval_SUITE.erl b/lib/stdlib/test/erl_eval_SUITE.erl
index 4b59cee99e..0bcf3c5b71 100644
--- a/lib/stdlib/test/erl_eval_SUITE.erl
+++ b/lib/stdlib/test/erl_eval_SUITE.erl
@@ -1199,7 +1199,7 @@ local_func(F, As0, Bs0) when is_atom(F) ->
lfh_value_extra() ->
%% Not documented.
- {value, fun(F, As) -> local_func_value(F, As) end, []}.
+ {value, fun(F, As, a1, a2) -> local_func_value(F, As) end, [a1, a2]}.
lfh_value() ->
{value, fun(F, As) -> local_func_value(F, As) end}.
diff --git a/lib/stdlib/test/erl_pp_SUITE.erl b/lib/stdlib/test/erl_pp_SUITE.erl
index bc811355ab..280c95b1aa 100644
--- a/lib/stdlib/test/erl_pp_SUITE.erl
+++ b/lib/stdlib/test/erl_pp_SUITE.erl
@@ -1161,7 +1161,7 @@ parse_forms2(String, Cont0, Line, Forms) ->
{done, {ok, Tokens, EndLine}, Chars} ->
{ok, Form} = erl_parse:parse_form(Tokens),
parse_forms2(Chars, [], EndLine, [Form | Forms]);
- {more, Cont} when element(3, Cont) =:= [] ->
+ {more, Cont} when element(4, Cont) =:= [] ->
%% extra spaces after forms...
parse_forms2([], Cont, Line, Forms);
{more, Cont} ->
diff --git a/lib/stdlib/test/sofs_SUITE.erl b/lib/stdlib/test/sofs_SUITE.erl
index 01de1f0600..d6f88a655e 100644
--- a/lib/stdlib/test/sofs_SUITE.erl
+++ b/lib/stdlib/test/sofs_SUITE.erl
@@ -1602,19 +1602,15 @@ relative_product_2(Conf) when is_list(Conf) ->
from_term([{{a},b}])}, ER)),
?line {'EXIT', {badarg, _}} = (catch relative_product({}, ER)),
- ?line eval(relative_product({relation([{a,b}])},
- from_term([],[{{atom},atom}])),
- ER),
- ?line eval(relative_product({relation([{a,b}]),relation([{a,1}])},
- from_term([{{b,1},{tjo,hej,sa}}])),
- from_term([{a,{tjo,hej,sa}}])),
- ?line eval(relative_product({relation([{a,b}]), ER},
- from_term([{{a,b},b}])),
- ER),
- ?line eval(relative_product({relation([{a,b},{c,a}]),
- relation([{a,1},{a,2}])},
- from_term([{{b,1},b1},{{b,2},b2}])),
- relation([{a,b1},{a,b2}])),
+ ?line relprod2({relation([{a,b}])}, from_term([],[{{atom},atom}]), ER),
+ ?line relprod2({relation([{a,b}]),relation([{a,1}])},
+ from_term([{{b,1},{tjo,hej,sa}}]),
+ from_term([{a,{tjo,hej,sa}}])),
+ ?line relprod2({relation([{a,b}]), ER}, from_term([{{a,b},b}]), ER),
+ ?line relprod2({relation([{a,b},{c,a}]),
+ relation([{a,1},{a,2}])},
+ from_term([{{b,1},b1},{{b,2},b2}]),
+ relation([{a,b1},{a,b2}])),
?line eval(relative_product({relation([{a,b}]), ER}),
from_term([],[{atom,{atom,atom}}])),
?line eval(relative_product({from_term([{{a,[a,b]},[a]}]),
@@ -1622,6 +1618,11 @@ relative_product_2(Conf) when is_list(Conf) ->
from_term([{{a,[a,b]},{[a],[[a,b]]}}])),
ok.
+relprod2(A1T, A2, R) ->
+ %% A tuple as first argument is the old interface:
+ eval(relative_product(A1T, A2), R),
+ eval(relative_product(tuple_to_list(A1T), A2), R).
+
product_1(suite) -> [];
product_1(doc) -> [""];
product_1(Conf) when is_list(Conf) ->
diff --git a/lib/stdlib/test/timer_simple_SUITE.erl b/lib/stdlib/test/timer_simple_SUITE.erl
index 852afa1a4d..dc751aad16 100644
--- a/lib/stdlib/test/timer_simple_SUITE.erl
+++ b/lib/stdlib/test/timer_simple_SUITE.erl
@@ -229,7 +229,7 @@ cancel2(Config) when is_list(Config) ->
tc(doc) -> "Test sleep/1 and tc/3.";
tc(suite) -> [];
tc(Config) when is_list(Config) ->
- % This should both sleep and tc/3
+ %% This should test both sleep and tc/3
?line {Res1, ok} = timer:tc(timer, sleep, [500]),
?line ok = if
Res1 < 500*1000 -> {too_early, Res1}; % Too early
@@ -237,13 +237,40 @@ tc(Config) when is_list(Config) ->
true -> ok
end,
- % This should both sleep and tc/2
+ %% tc/2
?line {Res2, ok} = timer:tc(fun(T) -> timer:sleep(T) end, [500]),
?line ok = if
Res2 < 500*1000 -> {too_early, Res2}; % Too early
Res2 > 800*1000 -> {too_late, Res2}; % Too much time
true -> ok
end,
+
+ %% tc/1
+ ?line {Res3, ok} = timer:tc(fun() -> timer:sleep(500) end),
+ ?line ok = if
+ Res3 < 500*1000 -> {too_early, Res3}; % Too early
+ Res3 > 800*1000 -> {too_late, Res3}; % Too much time
+ true -> ok
+ end,
+
+ %% Check that timer:tc don't catch errors
+ ?line ok = try timer:tc(erlang, exit, [foo])
+ catch exit:foo -> ok
+ end,
+
+ ?line ok = try timer:tc(fun(Reason) -> 1 = Reason end, [foo])
+ catch error:{badmatch,_} -> ok
+ end,
+
+ ?line ok = try timer:tc(fun() -> throw(foo) end)
+ catch foo -> ok
+ end,
+
+ %% Check that return values are propageted
+ Self = self(),
+ ?line {_, Self} = timer:tc(erlang, self, []),
+ ?line {_, Self} = timer:tc(fun(P) -> P end, [self()]),
+ ?line {_, Self} = timer:tc(fun() -> self() end),
?line Sec = timer:seconds(4),
?line Min = timer:minutes(4),