aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bootstrap/lib/compiler/ebin/beam_bool.beambin15648 -> 15672 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_split.beambin2496 -> 2496 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_utils.beambin13912 -> 13668 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/cerl.beambin32080 -> 32080 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/cerl_clauses.beambin2956 -> 2956 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/cerl_inline.beambin38692 -> 38688 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/core_parse.beambin57124 -> 57124 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/core_pp.beambin12796 -> 12020 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/rec_env.beambin4920 -> 4916 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/sys_core_fold.beambin52184 -> 52348 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/sys_pre_attributes.beambin3308 -> 3308 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/v3_codegen.beambin55848 -> 55848 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/v3_core.beambin53896 -> 53892 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/v3_kernel.beambin46656 -> 46676 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/disk_log.beambin35836 -> 35832 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/disk_log_1.beambin24876 -> 24884 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/file.beambin14452 -> 14456 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/global.beambin32244 -> 32244 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/group.beambin14036 -> 14032 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet.beambin23312 -> 23312 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_db.beambin27024 -> 27024 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_parse.beambin12916 -> 12912 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/kernel_config.beambin2764 -> 2764 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/dets.beambin53660 -> 53676 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/dets_v9.beambin49832 -> 49824 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/digraph_utils.beambin6816 -> 6816 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_eval.beambin30636 -> 30632 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_expand_records.beambin21760 -> 21760 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_lint.beambin90264 -> 90264 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_pp.beambin27352 -> 27344 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/file_sorter.beambin30400 -> 30400 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/filelib.beambin8044 -> 8048 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/filename.beambin14884 -> 14884 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/gen_event.beambin13468 -> 13416 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/gen_fsm.beambin9536 -> 9480 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/gen_server.beambin12500 -> 12448 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/gen_statem.beambin13588 -> 13492 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/lib.beambin9596 -> 9596 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/lists.beambin29912 -> 29904 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/otp_internal.beambin9632 -> 9636 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/qlc.beambin70116 -> 70112 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/qlc_pt.beambin76228 -> 76228 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/queue.beambin6184 -> 6180 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/shell.beambin30232 -> 30232 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/sofs.beambin40600 -> 40624 bytes
-rw-r--r--erts/doc/src/erl_tracer.xml62
-rw-r--r--erts/doc/src/erlang.xml5
-rw-r--r--erts/doc/src/erts_alloc.xml2
-rw-r--r--erts/doc/src/match_spec.xml149
-rw-r--r--erts/emulator/beam/beam_load.c1
-rw-r--r--erts/emulator/beam/binary.c2
-rw-r--r--erts/emulator/beam/erl_alloc.c30
-rw-r--r--erts/emulator/beam/erl_bif_re.c8
-rw-r--r--erts/emulator/beam/erl_message.h4
-rw-r--r--erts/emulator/beam/erl_nif.c28
-rw-r--r--erts/emulator/beam/erl_process.h4
-rw-r--r--erts/emulator/beam/erl_unicode.c58
-rw-r--r--erts/emulator/beam/global.h2
-rw-r--r--erts/emulator/hipe/hipe_mode_switch.c27
-rw-r--r--erts/emulator/test/alloc_SUITE.erl22
-rw-r--r--erts/emulator/test/port_trace_SUITE.erl44
-rw-r--r--erts/emulator/test/port_trace_SUITE_data/echo_drv.c36
-rw-r--r--erts/emulator/test/time_SUITE.erl77
-rw-r--r--erts/preloaded/ebin/erl_prim_loader.beambin55780 -> 55732 bytes
-rw-r--r--erts/preloaded/src/erl_prim_loader.erl6
-rw-r--r--lib/common_test/doc/src/ct_netconfc.xml7
-rw-r--r--lib/compiler/src/beam_bool.erl4
-rw-r--r--lib/compiler/src/beam_utils.erl103
-rw-r--r--lib/compiler/src/core_pp.erl55
-rw-r--r--lib/compiler/test/Makefile3
-rw-r--r--lib/compiler/test/andor_SUITE.erl63
-rw-r--r--lib/compiler/test/beam_block_SUITE.erl3
-rw-r--r--lib/compiler/test/beam_bool_SUITE.erl160
-rw-r--r--lib/compiler/test/compile_SUITE.erl32
-rw-r--r--lib/compiler/test/guard_SUITE.erl25
-rw-r--r--lib/compiler/test/test_lib.erl16
-rw-r--r--lib/compiler/test/trycatch_SUITE.erl3
-rw-r--r--lib/dialyzer/src/dialyzer_contracts.erl16
-rw-r--r--lib/eldap/src/eldap.erl7
-rw-r--r--lib/eldap/test/eldap_basic_SUITE.erl27
-rw-r--r--lib/erl_docgen/priv/xsl/db_html.xsl14
-rw-r--r--lib/erl_interface/test/ei_connect_SUITE_data/Makefile.src3
-rw-r--r--lib/erl_interface/test/ei_connect_SUITE_data/einode.c3
-rw-r--r--lib/hipe/cerl/erl_types.erl16
-rw-r--r--lib/inets/src/http_server/httpd_response.erl3
-rw-r--r--lib/inets/src/http_server/mod_htaccess.erl4
-rw-r--r--lib/kernel/doc/src/application.xml3
-rw-r--r--lib/kernel/doc/src/file.xml3
-rw-r--r--lib/kernel/doc/src/gen_sctp.xml6
-rw-r--r--lib/kernel/doc/src/gen_tcp.xml3
-rw-r--r--lib/kernel/doc/src/gen_udp.xml1
-rw-r--r--lib/kernel/doc/src/inet.xml4
-rw-r--r--lib/kernel/test/erl_prim_loader_SUITE.erl24
-rw-r--r--lib/os_mon/c_src/cpu_sup.c96
-rw-r--r--lib/os_mon/src/cpu_sup.erl3
-rw-r--r--lib/os_mon/src/memsup.erl2
-rw-r--r--lib/os_mon/test/cpu_sup_SUITE.erl2
-rw-r--r--lib/os_mon/test/memsup_SUITE.erl14
-rw-r--r--lib/percept/src/egd_primitives.erl514
-rw-r--r--lib/percept/src/egd_render.erl267
-rw-r--r--lib/percept/test/egd_SUITE.erl150
-rw-r--r--lib/public_key/test/pbe_SUITE.erl7
-rw-r--r--lib/public_key/test/pkits_SUITE.erl2
-rw-r--r--lib/public_key/test/public_key_SUITE.erl53
-rw-r--r--lib/runtime_tools/c_src/trace_ip_drv.c3
-rw-r--r--lib/runtime_tools/doc/src/dbg.xml60
-rw-r--r--lib/ssh/src/ssh_connection_handler.erl40
-rw-r--r--lib/ssl/src/ssl.erl31
-rw-r--r--lib/stdlib/doc/src/digraph.xml2
-rw-r--r--lib/stdlib/doc/src/digraph_utils.xml7
-rw-r--r--lib/stdlib/doc/src/erl_anno.xml4
-rw-r--r--lib/stdlib/doc/src/erl_parse.xml12
-rw-r--r--lib/stdlib/doc/src/ets.xml8
-rw-r--r--lib/stdlib/doc/src/sofs.xml3
-rw-r--r--lib/wx/api_gen/gl_gen.erl14
-rw-r--r--lib/wx/c_src/wxe_helpers.cpp8
-rw-r--r--lib/wx/include/gl.hrl4
-rw-r--r--lib/wx/test/wx_class_SUITE.erl4
118 files changed, 1480 insertions, 1008 deletions
diff --git a/bootstrap/lib/compiler/ebin/beam_bool.beam b/bootstrap/lib/compiler/ebin/beam_bool.beam
index a793db8bed..4a302a8709 100644
--- a/bootstrap/lib/compiler/ebin/beam_bool.beam
+++ b/bootstrap/lib/compiler/ebin/beam_bool.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_split.beam b/bootstrap/lib/compiler/ebin/beam_split.beam
index 3a02e2b17c..4a63468419 100644
--- a/bootstrap/lib/compiler/ebin/beam_split.beam
+++ b/bootstrap/lib/compiler/ebin/beam_split.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_utils.beam b/bootstrap/lib/compiler/ebin/beam_utils.beam
index 661cd1c60d..664140540c 100644
--- a/bootstrap/lib/compiler/ebin/beam_utils.beam
+++ b/bootstrap/lib/compiler/ebin/beam_utils.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/cerl.beam b/bootstrap/lib/compiler/ebin/cerl.beam
index 82bd89c17a..dea6cb4ee2 100644
--- a/bootstrap/lib/compiler/ebin/cerl.beam
+++ b/bootstrap/lib/compiler/ebin/cerl.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/cerl_clauses.beam b/bootstrap/lib/compiler/ebin/cerl_clauses.beam
index 95dd3f3cbb..cc4e3a92a3 100644
--- a/bootstrap/lib/compiler/ebin/cerl_clauses.beam
+++ b/bootstrap/lib/compiler/ebin/cerl_clauses.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/cerl_inline.beam b/bootstrap/lib/compiler/ebin/cerl_inline.beam
index ce1f13db6a..dcfb32d866 100644
--- a/bootstrap/lib/compiler/ebin/cerl_inline.beam
+++ b/bootstrap/lib/compiler/ebin/cerl_inline.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/core_parse.beam b/bootstrap/lib/compiler/ebin/core_parse.beam
index baf2c9d70f..920dbc922f 100644
--- a/bootstrap/lib/compiler/ebin/core_parse.beam
+++ b/bootstrap/lib/compiler/ebin/core_parse.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/core_pp.beam b/bootstrap/lib/compiler/ebin/core_pp.beam
index 6047596cb6..e274211c6c 100644
--- a/bootstrap/lib/compiler/ebin/core_pp.beam
+++ b/bootstrap/lib/compiler/ebin/core_pp.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/rec_env.beam b/bootstrap/lib/compiler/ebin/rec_env.beam
index 9388b5d4e1..a7c78175c3 100644
--- a/bootstrap/lib/compiler/ebin/rec_env.beam
+++ b/bootstrap/lib/compiler/ebin/rec_env.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/sys_core_fold.beam b/bootstrap/lib/compiler/ebin/sys_core_fold.beam
index 088d69fa2a..7d01ed81d5 100644
--- a/bootstrap/lib/compiler/ebin/sys_core_fold.beam
+++ b/bootstrap/lib/compiler/ebin/sys_core_fold.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/sys_pre_attributes.beam b/bootstrap/lib/compiler/ebin/sys_pre_attributes.beam
index 934a539ad9..58dff1b796 100644
--- a/bootstrap/lib/compiler/ebin/sys_pre_attributes.beam
+++ b/bootstrap/lib/compiler/ebin/sys_pre_attributes.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/v3_codegen.beam b/bootstrap/lib/compiler/ebin/v3_codegen.beam
index 0d76bb21e2..0923d4e678 100644
--- a/bootstrap/lib/compiler/ebin/v3_codegen.beam
+++ b/bootstrap/lib/compiler/ebin/v3_codegen.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/v3_core.beam b/bootstrap/lib/compiler/ebin/v3_core.beam
index 3b3b8f4208..7be50a757f 100644
--- a/bootstrap/lib/compiler/ebin/v3_core.beam
+++ b/bootstrap/lib/compiler/ebin/v3_core.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/v3_kernel.beam b/bootstrap/lib/compiler/ebin/v3_kernel.beam
index 5e3ae80d14..47eaf3b5e8 100644
--- a/bootstrap/lib/compiler/ebin/v3_kernel.beam
+++ b/bootstrap/lib/compiler/ebin/v3_kernel.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/disk_log.beam b/bootstrap/lib/kernel/ebin/disk_log.beam
index 998d4bca2f..5aa8bf7dc1 100644
--- a/bootstrap/lib/kernel/ebin/disk_log.beam
+++ b/bootstrap/lib/kernel/ebin/disk_log.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/disk_log_1.beam b/bootstrap/lib/kernel/ebin/disk_log_1.beam
index fc1c4781f1..cb627c10a5 100644
--- a/bootstrap/lib/kernel/ebin/disk_log_1.beam
+++ b/bootstrap/lib/kernel/ebin/disk_log_1.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/file.beam b/bootstrap/lib/kernel/ebin/file.beam
index c82dada559..28d72dfafc 100644
--- a/bootstrap/lib/kernel/ebin/file.beam
+++ b/bootstrap/lib/kernel/ebin/file.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/global.beam b/bootstrap/lib/kernel/ebin/global.beam
index b461d30baa..465dab3a52 100644
--- a/bootstrap/lib/kernel/ebin/global.beam
+++ b/bootstrap/lib/kernel/ebin/global.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/group.beam b/bootstrap/lib/kernel/ebin/group.beam
index 0511d1fa09..38eb0e7a6c 100644
--- a/bootstrap/lib/kernel/ebin/group.beam
+++ b/bootstrap/lib/kernel/ebin/group.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet.beam b/bootstrap/lib/kernel/ebin/inet.beam
index 60469432b9..8cfdf389ad 100644
--- a/bootstrap/lib/kernel/ebin/inet.beam
+++ b/bootstrap/lib/kernel/ebin/inet.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet_db.beam b/bootstrap/lib/kernel/ebin/inet_db.beam
index 557852c917..30ab40c93f 100644
--- a/bootstrap/lib/kernel/ebin/inet_db.beam
+++ b/bootstrap/lib/kernel/ebin/inet_db.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet_parse.beam b/bootstrap/lib/kernel/ebin/inet_parse.beam
index 30f05d5c09..c5c171aa54 100644
--- a/bootstrap/lib/kernel/ebin/inet_parse.beam
+++ b/bootstrap/lib/kernel/ebin/inet_parse.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/kernel_config.beam b/bootstrap/lib/kernel/ebin/kernel_config.beam
index 8691aff64a..8379f77e94 100644
--- a/bootstrap/lib/kernel/ebin/kernel_config.beam
+++ b/bootstrap/lib/kernel/ebin/kernel_config.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/dets.beam b/bootstrap/lib/stdlib/ebin/dets.beam
index 754663b531..0dfaca7a48 100644
--- a/bootstrap/lib/stdlib/ebin/dets.beam
+++ b/bootstrap/lib/stdlib/ebin/dets.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/dets_v9.beam b/bootstrap/lib/stdlib/ebin/dets_v9.beam
index 3e02f4b0be..f381b9b624 100644
--- a/bootstrap/lib/stdlib/ebin/dets_v9.beam
+++ b/bootstrap/lib/stdlib/ebin/dets_v9.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/digraph_utils.beam b/bootstrap/lib/stdlib/ebin/digraph_utils.beam
index 66777eeb8f..80e91be663 100644
--- a/bootstrap/lib/stdlib/ebin/digraph_utils.beam
+++ b/bootstrap/lib/stdlib/ebin/digraph_utils.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/erl_eval.beam b/bootstrap/lib/stdlib/ebin/erl_eval.beam
index 8793d70a39..d5bd46593c 100644
--- a/bootstrap/lib/stdlib/ebin/erl_eval.beam
+++ b/bootstrap/lib/stdlib/ebin/erl_eval.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/erl_expand_records.beam b/bootstrap/lib/stdlib/ebin/erl_expand_records.beam
index f6c0d0a732..e8ce1fa0da 100644
--- a/bootstrap/lib/stdlib/ebin/erl_expand_records.beam
+++ b/bootstrap/lib/stdlib/ebin/erl_expand_records.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/erl_lint.beam b/bootstrap/lib/stdlib/ebin/erl_lint.beam
index aeea1e2fcd..ebe80a32a8 100644
--- a/bootstrap/lib/stdlib/ebin/erl_lint.beam
+++ b/bootstrap/lib/stdlib/ebin/erl_lint.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/erl_pp.beam b/bootstrap/lib/stdlib/ebin/erl_pp.beam
index 9841362f9d..b3343c9ccb 100644
--- a/bootstrap/lib/stdlib/ebin/erl_pp.beam
+++ b/bootstrap/lib/stdlib/ebin/erl_pp.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/file_sorter.beam b/bootstrap/lib/stdlib/ebin/file_sorter.beam
index ac4f1a36f1..03d9020bb5 100644
--- a/bootstrap/lib/stdlib/ebin/file_sorter.beam
+++ b/bootstrap/lib/stdlib/ebin/file_sorter.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/filelib.beam b/bootstrap/lib/stdlib/ebin/filelib.beam
index a9783ed990..904edee66f 100644
--- a/bootstrap/lib/stdlib/ebin/filelib.beam
+++ b/bootstrap/lib/stdlib/ebin/filelib.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/filename.beam b/bootstrap/lib/stdlib/ebin/filename.beam
index b6248fe460..c129ac4f97 100644
--- a/bootstrap/lib/stdlib/ebin/filename.beam
+++ b/bootstrap/lib/stdlib/ebin/filename.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/gen_event.beam b/bootstrap/lib/stdlib/ebin/gen_event.beam
index 2486647f46..b53ac26280 100644
--- a/bootstrap/lib/stdlib/ebin/gen_event.beam
+++ b/bootstrap/lib/stdlib/ebin/gen_event.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/gen_fsm.beam b/bootstrap/lib/stdlib/ebin/gen_fsm.beam
index dbf38090af..595574585b 100644
--- a/bootstrap/lib/stdlib/ebin/gen_fsm.beam
+++ b/bootstrap/lib/stdlib/ebin/gen_fsm.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/gen_server.beam b/bootstrap/lib/stdlib/ebin/gen_server.beam
index e7026a2a9a..3097207512 100644
--- a/bootstrap/lib/stdlib/ebin/gen_server.beam
+++ b/bootstrap/lib/stdlib/ebin/gen_server.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/gen_statem.beam b/bootstrap/lib/stdlib/ebin/gen_statem.beam
index 5a3fd2a1a5..3dc104f1c3 100644
--- a/bootstrap/lib/stdlib/ebin/gen_statem.beam
+++ b/bootstrap/lib/stdlib/ebin/gen_statem.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/lib.beam b/bootstrap/lib/stdlib/ebin/lib.beam
index 541ea59421..06ddba221a 100644
--- a/bootstrap/lib/stdlib/ebin/lib.beam
+++ b/bootstrap/lib/stdlib/ebin/lib.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/lists.beam b/bootstrap/lib/stdlib/ebin/lists.beam
index 422a9bd214..22705c8a9a 100644
--- a/bootstrap/lib/stdlib/ebin/lists.beam
+++ b/bootstrap/lib/stdlib/ebin/lists.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/otp_internal.beam b/bootstrap/lib/stdlib/ebin/otp_internal.beam
index e1ebd34afd..ce8fc8a5c5 100644
--- a/bootstrap/lib/stdlib/ebin/otp_internal.beam
+++ b/bootstrap/lib/stdlib/ebin/otp_internal.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/qlc.beam b/bootstrap/lib/stdlib/ebin/qlc.beam
index f0ed1e961b..fa3240810d 100644
--- a/bootstrap/lib/stdlib/ebin/qlc.beam
+++ b/bootstrap/lib/stdlib/ebin/qlc.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/qlc_pt.beam b/bootstrap/lib/stdlib/ebin/qlc_pt.beam
index 17c698de60..4a065ec57f 100644
--- a/bootstrap/lib/stdlib/ebin/qlc_pt.beam
+++ b/bootstrap/lib/stdlib/ebin/qlc_pt.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/queue.beam b/bootstrap/lib/stdlib/ebin/queue.beam
index 4365c5518d..a63a321330 100644
--- a/bootstrap/lib/stdlib/ebin/queue.beam
+++ b/bootstrap/lib/stdlib/ebin/queue.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/shell.beam b/bootstrap/lib/stdlib/ebin/shell.beam
index 9fa5727aa5..b0c98f4b98 100644
--- a/bootstrap/lib/stdlib/ebin/shell.beam
+++ b/bootstrap/lib/stdlib/ebin/shell.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/sofs.beam b/bootstrap/lib/stdlib/ebin/sofs.beam
index 01f7810764..5099d4ecc0 100644
--- a/bootstrap/lib/stdlib/ebin/sofs.beam
+++ b/bootstrap/lib/stdlib/ebin/sofs.beam
Binary files differ
diff --git a/erts/doc/src/erl_tracer.xml b/erts/doc/src/erl_tracer.xml
index 7fd5512b33..d4c8bbad31 100644
--- a/erts/doc/src/erl_tracer.xml
+++ b/erts/doc/src/erl_tracer.xml
@@ -67,7 +67,7 @@
<desc>
<p>The different trace tags that the tracer will be called with.
Each trace tag is described in greater detail in
- <seealso marker="#trace">Module:trace/6</seealso>
+ <seealso marker="#Module:trace/6">Module:trace/6</seealso>
</p>
</desc>
</datatype>
@@ -81,7 +81,7 @@
<datatype>
<name name="trace_opts" />
<desc>
- <p>The options for the tracee.
+ <p>The options for the tracee.</p>
<taglist>
<tag><c>timestamp</c></tag>
<item>If not set to <c>undefined</c>, the tracer has been requested to
@@ -93,7 +93,6 @@
<item>Set to a number if the scheduler id is to be included by the tracer.
Otherwise it is set to <c>undefined</c>.</item>
</taglist>
- </p>
</desc>
</datatype>
<datatype>
@@ -114,30 +113,30 @@
<p>The following functions
should be exported from a <c>erl_tracer</c> callback module.</p>
<taglist>
- <tag><seealso marker="#enabled"><c>Module:enabled/3</c></seealso></tag>
+ <tag><seealso marker="#Module:enabled/3"><c>Module:enabled/3</c></seealso></tag>
<item>Mandatory</item>
- <tag><seealso marker="#trace"><c>Module:trace/6</c></seealso></tag>
+ <tag><seealso marker="#Module:trace/6"><c>Module:trace/6</c></seealso></tag>
<item>Mandatory</item>
- <tag><seealso marker="#enabled_procs"><c>Module:enabled_procs/3</c></seealso></tag>
+ <tag><seealso marker="#Module:enabled_procs/3"><c>Module:enabled_procs/3</c></seealso></tag>
<item>Optional</item>
- <tag><seealso marker="#trace_procs"><c>Module:trace_procs/6</c></seealso></tag>
+ <tag><seealso marker="#Module:trace_procs/6"><c>Module:trace_procs/6</c></seealso></tag>
<item>Optional</item>
- <tag><seealso marker="#enabled_ports"><c>Module:enabled_ports/3</c></seealso></tag>
+ <tag><seealso marker="#Module:enabled_ports/3"><c>Module:enabled_ports/3</c></seealso></tag>
<item>Optional</item>
- <tag><seealso marker="#trace_ports"><c>Module:trace_ports/6</c></seealso></tag>
+ <tag><seealso marker="#Module:trace_ports/6"><c>Module:trace_ports/6</c></seealso></tag>
<item>Optional</item>
- <tag><seealso marker="#enabled_running_ports"><c>Module:enabled_running_ports/3</c></seealso></tag>
+ <tag><seealso marker="#Module:enabled_running_ports/3"><c>Module:enabled_running_ports/3</c></seealso></tag>
<item>Optional</item>
- <tag><seealso marker="#trace_running_ports"><c>Module:trace_running_ports/6</c></seealso></tag>
+ <tag><seealso marker="#Module:trace_running_ports/6"><c>Module:trace_running_ports/6</c></seealso></tag>
<item>Optional</item>
- <tag><seealso marker="#enabled_running_procs"><c>Module:enabled_running_procs/3</c></seealso></tag>
+ <tag><seealso marker="#Module:enabled_running_procs/3"><c>Module:enabled_running_procs/3</c></seealso></tag>
<item>Optional</item>
- <tag><seealso marker="#trace_running_procs"><c>Module:trace_running_procs/6</c></seealso></tag>
+ <tag><seealso marker="#Module:trace_running_procs/6"><c>Module:trace_running_procs/6</c></seealso></tag>
<item>Optional</item>
</taglist>
</section>
- <marker id="enabled"></marker>
+
<funcs>
<func>
<name>Module:enabled(TraceTag, TracerState, Tracee) -> Result</name>
@@ -166,7 +165,6 @@
is important that it is both fast and side effect free.</p>
</desc>
</func>
- <marker id="trace"></marker>
<func>
<name>Module:trace(TraceTag, TracerState, Tracee, FirstTraceTerm, SecondTraceTerm, Opts) -> Result</name>
<fsummary>Check if a trace event should be generated.</fsummary>
@@ -181,7 +179,7 @@
</type>
<desc>
<p>This callback will be called when a tracepoint is triggered and
- the <seealso marker="#enabled">Module:enabled/3</seealso>
+ the <seealso marker="#Module:enabled/3">Module:enabled/3</seealso>
callback returned <c>trace</c>. In it any side effects needed by
the tracer should be done. The tracepoint payload is located in
the <c>FirstTraceTerm</c> and <c>SecondTraceTerm</c>. The content
@@ -212,7 +210,6 @@
</desc>
</func>
- <marker id="enabled_procs"></marker>
<func>
<name>Module:enabled_procs(TraceTag, TracerState, Tracee) -> Result</name>
<fsummary>Check if a trace event should be generated.</fsummary>
@@ -230,7 +227,6 @@
</desc>
</func>
- <marker id="trace_procs"></marker>
<func>
<name>Module:trace_procs(TraceTag, TracerState, Tracee, FirstTraceTerm, SecondTraceTerm, Opts) -> Result</name>
<fsummary>Check if a trace event should be generated.</fsummary>
@@ -245,13 +241,12 @@
</type>
<desc>
<p>This callback will be called when a tracepoint is triggered and
- the <seealso marker="#enabled_procs">Module:enabled_procs/3</seealso>
+ the <seealso marker="#Module:enabled_procs/3">Module:enabled_procs/3</seealso>
callback returned <c>trace</c>.</p>
<p>If <c>trace_procs/6</c> is not defined <c>trace/6</c> will be called instead.</p>
</desc>
</func>
- <marker id="enabled_ports"></marker>
<func>
<name>Module:enabled_ports(TraceTag, TracerState, Tracee) -> Result</name>
<fsummary>Check if a trace event should be generated.</fsummary>
@@ -269,7 +264,6 @@
</desc>
</func>
- <marker id="trace_ports"></marker>
<func>
<name>Module:trace_ports(TraceTag, TracerState, Tracee, FirstTraceTerm, SecondTraceTerm, Opts) -> Result</name>
<fsummary>Check if a trace event should be generated.</fsummary>
@@ -284,13 +278,12 @@
</type>
<desc>
<p>This callback will be called when a tracepoint is triggered and
- the <seealso marker="#enabled_ports">Module:enabled_ports/3</seealso>
+ the <seealso marker="#Module:enabled_ports/3">Module:enabled_ports/3</seealso>
callback returned <c>trace</c>.</p>
<p>If <c>trace_ports/6</c> is not defined <c>trace/6</c> will be called instead.</p>
</desc>
</func>
- <marker id="enabled_running_procs"></marker>
<func>
<name>Module:enabled_running_procs(TraceTag, TracerState, Tracee) -> Result</name>
<fsummary>Check if a trace event should be generated.</fsummary>
@@ -308,7 +301,6 @@
</desc>
</func>
- <marker id="trace_running_procs"></marker>
<func>
<name>Module:trace_running_procs(TraceTag, TracerState, Tracee, FirstTraceTerm, SecondTraceTerm, Opts) -> Result</name>
<fsummary>Check if a trace event should be generated.</fsummary>
@@ -323,13 +315,12 @@
</type>
<desc>
<p>This callback will be called when a tracepoint is triggered and
- the <seealso marker="#enabled_running_procs">Module:enabled_running_procs/3</seealso>
+ the <seealso marker="#Module:enabled_running_procs/3">Module:enabled_running_procs/3</seealso>
callback returned <c>trace</c>.</p>
<p>If <c>trace_running_procs/6</c> is not defined <c>trace/6</c> will be called instead.</p>
</desc>
</func>
- <marker id="enabled_running_ports"></marker>
<func>
<name>Module:enabled_running_ports(TraceTag, TracerState, Tracee) -> Result</name>
<fsummary>Check if a trace event should be generated.</fsummary>
@@ -347,7 +338,6 @@
</desc>
</func>
- <marker id="trace_running_ports"></marker>
<func>
<name>Module:trace_running_ports(TraceTag, TracerState, Tracee, FirstTraceTerm, SecondTraceTerm, Opts) -> Result</name>
<fsummary>Check if a trace event should be generated.</fsummary>
@@ -362,13 +352,12 @@
</type>
<desc>
<p>This callback will be called when a tracepoint is triggered and
- the <seealso marker="#enabled_running_ports">Module:enabled_running_ports/3</seealso>
+ the <seealso marker="#Module:enabled_running_ports/3">Module:enabled_running_ports/3</seealso>
callback returned <c>trace</c>.</p>
<p>If <c>trace_running_ports/6</c> is not defined <c>trace/6</c> will be called instead.</p>
</desc>
</func>
- <marker id="enabled_call"></marker>
<func>
<name>Module:enabled_call(TraceTag, TracerState, Tracee) -> Result</name>
<fsummary>Check if a trace event should be generated.</fsummary>
@@ -386,7 +375,6 @@
</desc>
</func>
- <marker id="trace_call"></marker>
<func>
<name>Module:trace_call(TraceTag, TracerState, Tracee, FirstTraceTerm, SecondTraceTerm, Opts) -> Result</name>
<fsummary>Check if a trace event should be generated.</fsummary>
@@ -401,13 +389,12 @@
</type>
<desc>
<p>This callback will be called when a tracepoint is triggered and
- the <seealso marker="#enabled_call">Module:enabled_call/3</seealso>
+ the <seealso marker="#Module:enabled_call/3">Module:enabled_call/3</seealso>
callback returned <c>trace</c>.</p>
<p>If <c>trace_call/6</c> is not defined <c>trace/6</c> will be called instead.</p>
</desc>
</func>
- <marker id="enabled_send"></marker>
<func>
<name>Module:enabled_send(TraceTag, TracerState, Tracee) -> Result</name>
<fsummary>Check if a trace event should be generated.</fsummary>
@@ -425,7 +412,6 @@
</desc>
</func>
- <marker id="trace_send"></marker>
<func>
<name>Module:trace_send(TraceTag, TracerState, Tracee, FirstTraceTerm, SecondTraceTerm, Opts) -> Result</name>
<fsummary>Check if a trace event should be generated.</fsummary>
@@ -440,13 +426,12 @@
</type>
<desc>
<p>This callback will be called when a tracepoint is triggered and
- the <seealso marker="#enabled_send">Module:enabled_send/3</seealso>
+ the <seealso marker="#Module:enabled_send/3">Module:enabled_send/3</seealso>
callback returned <c>trace</c>.</p>
<p>If <c>trace_send/6</c> is not defined <c>trace/6</c> will be called instead.</p>
</desc>
</func>
- <marker id="enabled_receive"></marker>
<func>
<name>Module:enabled_receive(TraceTag, TracerState, Tracee) -> Result</name>
<fsummary>Check if a trace event should be generated.</fsummary>
@@ -464,7 +449,6 @@
</desc>
</func>
- <marker id="trace_receive"></marker>
<func>
<name>Module:trace_receive(TraceTag, TracerState, Tracee, FirstTraceTerm, SecondTraceTerm, Opts) -> Result</name>
<fsummary>Check if a trace event should be generated.</fsummary>
@@ -479,13 +463,12 @@
</type>
<desc>
<p>This callback will be called when a tracepoint is triggered and
- the <seealso marker="#enabled_receive">Module:enabled_receive/3</seealso>
+ the <seealso marker="#Module:enabled_receive/3">Module:enabled_receive/3</seealso>
callback returned <c>trace</c>.</p>
<p>If <c>trace_receive/6</c> is not defined <c>trace/6</c> will be called instead.</p>
</desc>
</func>
- <marker id="enabled_garbage_collection"></marker>
<func>
<name>Module:enabled_garbage_collection(TraceTag, TracerState, Tracee) -> Result</name>
<fsummary>Check if a trace event should be generated.</fsummary>
@@ -503,7 +486,6 @@
</desc>
</func>
- <marker id="trace_garbage_collection"></marker>
<func>
<name>Module:trace_garbage_collection(TraceTag, TracerState, Tracee, FirstTraceTerm, SecondTraceTerm, Opts) -> Result</name>
<fsummary>Check if a trace event should be generated.</fsummary>
@@ -518,7 +500,7 @@
</type>
<desc>
<p>This callback will be called when a tracepoint is triggered and
- the <seealso marker="#enabled_garbage_collection">Module:enabled_garbage_collection/3</seealso>
+ the <seealso marker="#Module:enabled_garbage_collection/3">Module:enabled_garbage_collection/3</seealso>
callback returned <c>trace</c>.</p>
<p>If <c>trace_garbage_collection/6</c> is not defined <c>trace/6</c> will be called instead.</p>
</desc>
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index e0723127f2..9287b32fec 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -52,7 +52,6 @@
<datatype>
<name>ext_binary()</name>
<desc>
- <marker id="type-ext_binary"></marker>
<p>A binary data object, structured according to
the Erlang external term format.</p>
</desc>
@@ -5070,10 +5069,6 @@ os_prompt% </pre>
<p>Stops the execution of the calling process with an
exception of given class, reason, and call stack backtrace
(<em>stacktrace</em>).</p>
- <warning>
- <p>This BIF is intended for debugging. Avoid to use it in applications,
- unless you really know what you are doing.</p>
- </warning>
<p><c><anno>Class</anno></c> is <c>error</c>, <c>exit</c>, or
<c>throw</c>. So, if it were not for the stacktrace,
<c>erlang:raise(<anno>Class</anno>, <anno>Reason</anno>,
diff --git a/erts/doc/src/erts_alloc.xml b/erts/doc/src/erts_alloc.xml
index 70775b9f0f..9aef1c0b1f 100644
--- a/erts/doc/src/erts_alloc.xml
+++ b/erts/doc/src/erts_alloc.xml
@@ -583,7 +583,7 @@
</taglist>
<p>The following flag is special for <c>exec_alloc</c>:</p>
<taglist>
- <tag><marker id="MIscs"/><c><![CDATA[+MXscs <size in MB>]]></c></tag>
+ <tag><marker id="MXscs"/><c><![CDATA[+MXscs <size in MB>]]></c></tag>
<item>
<c>exec_alloc</c> super carrier size (in MB). The amount of
<em>virtual</em> address space reserved for native executable code
diff --git a/erts/doc/src/match_spec.xml b/erts/doc/src/match_spec.xml
index 3944f24f84..7be3d15de6 100644
--- a/erts/doc/src/match_spec.xml
+++ b/erts/doc/src/match_spec.xml
@@ -33,21 +33,15 @@
<file>match_spec.xml</file>
</header>
<p>A "match specification" (match_spec) is an Erlang term describing a
- small "program" that will try to match something (either the
- parameters to a function as used in the <c><![CDATA[erlang:trace_pattern/2]]></c>
- BIF, or the objects in an ETS table.).
+ small "program" that will try to match something. It can be used
+ to either control tracing with
+ <seealso marker="erlang#trace_pattern/3">erlang:trace_pattern/3</seealso>
+ or to search for objects in an ETS table with for example
+ <seealso marker="stdlib:ets#select/2">ets:select/2</seealso>.
The match_spec in many ways works like a small function in Erlang, but is
interpreted/compiled by the Erlang runtime system to something much more
efficient than calling an Erlang function. The match_spec is also
very limited compared to the expressiveness of real Erlang functions.</p>
- <p>Match specifications are given to the BIF <c><![CDATA[erlang:trace_pattern/2]]></c> to
- execute matching of function arguments as well as to define some actions
- to be taken when the match succeeds (the <c><![CDATA[MatchBody]]></c> part). Match
- specifications can also be used in ETS, to specify objects to be
- returned from an <c><![CDATA[ets:select/2]]></c> call (or other select
- calls). The semantics and restrictions differ slightly when using
- match specifications for tracing and in ETS, the differences are
- defined in a separate paragraph below.</p>
<p>The most notable difference between a match_spec and an Erlang fun is
of course the syntax. Match specifications are Erlang terms, not
Erlang code. A match_spec also has a somewhat strange concept of
@@ -382,6 +376,51 @@
the pid() of the current process.</p>
</section>
+ <marker id="match_target"></marker>
+ <section>
+ <title>Match target</title>
+ <p>Each execution of a match specification is done against
+ a match target term. The format and content of the target term
+ depends on the context in which the match is done. The match
+ target for ETS is always a full table tuple. The match target
+ for call trace is always a list of all function arguments. The
+ match target for event trace depends on the event type, see
+ table below.</p>
+ <table>
+ <row>
+ <cell align="left" valign="middle">Context</cell>
+ <cell align="left" valign="middle">Type</cell>
+ <cell align="left" valign="middle">Match target</cell>
+ <cell align="left" valign="middle">Description</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">ETS</cell>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">{Key, Value1, Value2, ...}</cell>
+ <cell align="left" valign="middle">A table object</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">Trace</cell>
+ <cell align="left" valign="middle">call</cell>
+ <cell align="left" valign="middle">[Arg1, Arg2, ...]</cell>
+ <cell align="left" valign="middle">Function arguments</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">Trace</cell>
+ <cell align="left" valign="middle">send</cell>
+ <cell align="left" valign="middle">[Receiver, Message]</cell>
+ <cell align="left" valign="middle">Receiving process/port and message term</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">Trace</cell>
+ <cell align="left" valign="middle">'receive'</cell>
+ <cell align="left" valign="middle">[Node, Sender, Message]</cell>
+ <cell align="left" valign="middle">Sending node, process/port and message term</cell>
+ </row>
+ <tcaption>Match target depending on context</tcaption>
+ </table>
+ </section>
+
<section>
<title>Variables and literals</title>
<p>Variables take the form <c><![CDATA['$<number>']]></c> where
@@ -396,10 +435,8 @@
<c><![CDATA[MatchCondition]]></c> parts, only variables bound previously may
be used. As a special case, in the
<c><![CDATA[MatchCondition/MatchBody]]></c> parts, the variable <c><![CDATA['$_']]></c>
- expands to the whole expression which matched the
- <c><![CDATA[MatchHead]]></c> (i.e., the whole parameter list to the possibly
- traced function or the whole matching object in the ets table)
- and the variable <c><![CDATA['$$']]></c> expands to a list
+ expands to the whole <seealso marker="#match_target">match target</seealso>
+ term and the variable <c><![CDATA['$$']]></c> expands to a list
of the values of all bound variables in order
(i.e. <c><![CDATA[['$1','$2', ...]]]></c>).
</p>
@@ -480,8 +517,8 @@
<p>For each tuple in the <c><![CDATA[MatchExpression]]></c> list and while no
match has succeeded:</p>
<list type="bulleted">
- <item>Match the <c><![CDATA[MatchHead]]></c> part against the arguments to the
- function,
+ <item>Match the <c><![CDATA[MatchHead]]></c> part against the
+ match target term,
binding the <c><![CDATA['$<number>']]></c> variables (much like in
<c><![CDATA[ets:match/2]]></c>).
If the <c><![CDATA[MatchHead]]></c> cannot match the arguments, the match fails.
@@ -522,13 +559,10 @@
term. The <c><![CDATA[ActionTerm]]></c>'s are executed as in an imperative
language, i.e. for their side effects. Functions with side effects
are also allowed when tracing.</p>
- <p>In ETS the match head is a <c><![CDATA[tuple()]]></c> (or a single match
- variable) while it is a list (or a single match variable) when
- tracing.</p>
</section>
<section>
- <title>ETS Examples</title>
+ <title>Tracing Examples</title>
<p>Match an argument list of three where the first and third arguments
are equal:</p>
<code type="none"><![CDATA[
@@ -585,42 +619,6 @@
parameter list with a single variable is a special case. In all
other cases the <c><![CDATA[MatchHead]]></c> has to be a <em>proper</em> list.
</p>
- <p>Match all objects in an ets table where the first element is
- the atom 'strider' and the tuple arity is 3 and return the whole
- object.</p>
- <code type="none"><![CDATA[
-[{{strider,'_','_'},
- [],
- ['$_']}]
- ]]></code>
- <p>Match all objects in an ets table with arity &gt; 1 and the first
- element is 'gandalf', return element 2.</p>
- <code type="none"><![CDATA[
-[{'$1',
- [{'==', gandalf, {element, 1, '$1'}},{'>=',{size, '$1'},2}],
- [{element,2,'$1'}]}]
- ]]></code>
- <p>In the above example, if the first element had been the key,
- it's much more efficient to match that key in the <c><![CDATA[MatchHead]]></c>
- part than in the <c><![CDATA[MatchConditions]]></c> part. The search space of
- the tables is restricted with regards to the <c><![CDATA[MatchHead]]></c> so
- that only objects with the matching key are searched.
- </p>
- <p>Match tuples of 3 elements where the second element is either
- 'merry' or 'pippin', return the whole objects.</p>
- <code type="none"><![CDATA[
-[{{'_',merry,'_'},
- [],
- ['$_']},
- {{'_',pippin,'_'},
- [],
- ['$_']}]
- ]]></code>
- <p>The function <c><![CDATA[ets:test_ms/2]]></c> can be useful for testing
- complicated ets matches.</p>
- </section>
- <section>
- <title>Tracing Examples</title>
<p>Only generate trace message if trace control word is set to 1:</p>
<code type="none"><![CDATA[
[{'_',
@@ -658,5 +656,42 @@
{'_',[],[]}]
]]></code>
</section>
+
+ <section>
+ <title>ETS Examples</title>
+ <p>Match all objects in an ets table where the first element is
+ the atom 'strider' and the tuple arity is 3 and return the whole
+ object.</p>
+ <code type="none"><![CDATA[
+[{{strider,'_','_'},
+ [],
+ ['$_']}]
+ ]]></code>
+ <p>Match all objects in an ets table with arity &gt; 1 and the first
+ element is 'gandalf', return element 2.</p>
+ <code type="none"><![CDATA[
+[{'$1',
+ [{'==', gandalf, {element, 1, '$1'}},{'>=',{size, '$1'},2}],
+ [{element,2,'$1'}]}]
+ ]]></code>
+ <p>In the above example, if the first element had been the key,
+ it's much more efficient to match that key in the <c><![CDATA[MatchHead]]></c>
+ part than in the <c><![CDATA[MatchConditions]]></c> part. The search space of
+ the tables is restricted with regards to the <c><![CDATA[MatchHead]]></c> so
+ that only objects with the matching key are searched.
+ </p>
+ <p>Match tuples of 3 elements where the second element is either
+ 'merry' or 'pippin', return the whole objects.</p>
+ <code type="none"><![CDATA[
+[{{'_',merry,'_'},
+ [],
+ ['$_']},
+ {{'_',pippin,'_'},
+ [],
+ ['$_']}]
+ ]]></code>
+ <p>The function <c><![CDATA[ets:test_ms/2]]></c> can be useful for testing
+ complicated ets matches.</p>
+ </section>
</chapter>
diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c
index 95489d9a63..0c2743beb2 100644
--- a/erts/emulator/beam/beam_load.c
+++ b/erts/emulator/beam/beam_load.c
@@ -4424,6 +4424,7 @@ gen_get_map_elements(LoaderState* stp, GenOpArg Fail, GenOpArg Src,
int good_hash;
#endif
+ ERTS_UNDEF(hx, 0);
ASSERT(Size.type == TAG_u);
NEW_GENOP(stp, op);
diff --git a/erts/emulator/beam/binary.c b/erts/emulator/beam/binary.c
index cfd8fbe2f5..071a356260 100644
--- a/erts/emulator/beam/binary.c
+++ b/erts/emulator/beam/binary.c
@@ -117,7 +117,7 @@ new_binary(Process *p, byte *buf, Uint len)
* When heap binary is not desired...
*/
-Eterm erts_new_mso_binary(Process *p, byte *buf, int len)
+Eterm erts_new_mso_binary(Process *p, byte *buf, Uint len)
{
ProcBin* pb;
Binary* bptr;
diff --git a/erts/emulator/beam/erl_alloc.c b/erts/emulator/beam/erl_alloc.c
index c367d4162c..3c2c9def3b 100644
--- a/erts/emulator/beam/erl_alloc.c
+++ b/erts/emulator/beam/erl_alloc.c
@@ -137,10 +137,13 @@ static ErtsAllocatorState_t exec_alloc_state;
#endif
static ErtsAllocatorState_t test_alloc_state;
-#define ERTS_ALC_INFO_A_ALLOC_UTIL (ERTS_ALC_A_MAX + 1)
-#define ERTS_ALC_INFO_A_MSEG_ALLOC (ERTS_ALC_A_MAX + 2)
-#define ERTS_ALC_INFO_A_ERTS_MMAP (ERTS_ALC_A_MAX + 3)
-#define ERTS_ALC_INFO_A_MAX ERTS_ALC_INFO_A_ERTS_MMAP
+enum {
+ ERTS_ALC_INFO_A_ALLOC_UTIL = ERTS_ALC_A_MAX + 1,
+ ERTS_ALC_INFO_A_MSEG_ALLOC,
+ ERTS_ALC_INFO_A_ERTS_MMAP,
+ ERTS_ALC_INFO_A_DISABLED_EXEC, /* fake a disabled "exec_alloc" */
+ ERTS_ALC_INFO_A_END
+};
typedef struct {
erts_smp_atomic32_t refc;
@@ -150,7 +153,7 @@ typedef struct {
Process *proc;
Eterm ref;
Eterm ref_heap[REF_THING_SIZE];
- int allocs[ERTS_ALC_INFO_A_MAX - ERTS_ALC_A_MIN + 1 + 1];
+ int allocs[ERTS_ALC_INFO_A_END - ERTS_ALC_A_MIN + 1];
} ErtsAllocInfoReq;
ERTS_SCHED_PREF_QUICK_ALLOC_IMPL(aireq,
@@ -3260,6 +3263,12 @@ reply_alloc_info(void *vair)
am_false);
#endif
break;
+#ifndef ERTS_ALC_A_EXEC
+ case ERTS_ALC_INFO_A_DISABLED_EXEC:
+ alloc_atom = erts_bld_atom(hpp, szp, "exec_alloc");
+ ainfo = erts_bld_tuple2(hpp, szp, alloc_atom, am_false);
+ break;
+#endif
default:
alloc_atom = erts_bld_atom(hpp, szp,
(char *) ERTS_ALC_A2AD(ai));
@@ -3287,7 +3296,8 @@ reply_alloc_info(void *vair)
switch (ai) {
case ERTS_ALC_A_SYSTEM:
case ERTS_ALC_INFO_A_ALLOC_UTIL:
- case ERTS_ALC_INFO_A_ERTS_MMAP:
+ case ERTS_ALC_INFO_A_ERTS_MMAP:
+ case ERTS_ALC_INFO_A_DISABLED_EXEC:
break;
case ERTS_ALC_INFO_A_MSEG_ALLOC:
#if HAVE_ERTS_MSEG && defined(ERTS_SMP)
@@ -3359,7 +3369,7 @@ erts_request_alloc_info(struct process *c_p,
int internal)
{
ErtsAllocInfoReq *air = aireq_alloc();
- Eterm req_ai[ERTS_ALC_INFO_A_MAX+1] = {0};
+ Eterm req_ai[ERTS_ALC_INFO_A_END] = {0};
Eterm alist;
Eterm *hp;
int airix = 0, ai;
@@ -3399,6 +3409,12 @@ erts_request_alloc_info(struct process *c_p,
ai = ERTS_ALC_INFO_A_ERTS_MMAP;
goto save_alloc;
}
+#ifndef ERTS_ALC_A_EXEC
+ if (erts_is_atom_str("exec_alloc", alloc, 0)) {
+ ai = ERTS_ALC_INFO_A_DISABLED_EXEC;
+ goto save_alloc;
+ }
+#endif
if (erts_is_atom_str("alloc_util", alloc, 0)) {
ai = ERTS_ALC_INFO_A_ALLOC_UTIL;
save_alloc:
diff --git a/erts/emulator/beam/erl_bif_re.c b/erts/emulator/beam/erl_bif_re.c
index f4daecd2a4..ff7746ce1d 100644
--- a/erts/emulator/beam/erl_bif_re.c
+++ b/erts/emulator/beam/erl_bif_re.c
@@ -630,9 +630,15 @@ static Eterm build_exec_return(Process *p, int rc, RestartContext *restartp, Ete
}
} else {
ReturnInfo *ri;
- ReturnInfo defri = {RetIndex,0,{0}};
+ ReturnInfo defri;
if (restartp->ret_info == NULL) {
+ /* OpenBSD 5.8 gcc compiler for some reason creates
+ bad code if the above initialization is done
+ inline with the struct. So don't do that. */
+ defri.type = RetIndex;
+ defri.num_spec = 0;
+ defri.v[0] = 0;
ri = &defri;
} else {
ri = restartp->ret_info;
diff --git a/erts/emulator/beam/erl_message.h b/erts/emulator/beam/erl_message.h
index 851ac37fda..4493df1c1a 100644
--- a/erts/emulator/beam/erl_message.h
+++ b/erts/emulator/beam/erl_message.h
@@ -112,8 +112,8 @@ typedef struct erl_heap_fragment ErlHeapFragment;
struct erl_heap_fragment {
ErlHeapFragment* next; /* Next heap fragment */
ErlOffHeap off_heap; /* Offset heap data. */
- unsigned alloc_size; /* Size in (half)words of mem */
- unsigned used_size; /* With terms to be moved to heap by GC */
+ Uint alloc_size; /* Size in (half)words of mem */
+ Uint used_size; /* With terms to be moved to heap by GC */
Eterm mem[1]; /* Data */
};
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c
index 159dc66ad5..606b73c7b5 100644
--- a/erts/emulator/beam/erl_nif.c
+++ b/erts/emulator/beam/erl_nif.c
@@ -96,7 +96,7 @@ void dtrace_nifenv_str(ErlNifEnv *, char *);
#endif
#define MIN_HEAP_FRAG_SZ 200
-static Eterm* alloc_heap_heavy(ErlNifEnv* env, unsigned need, Eterm* hp);
+static Eterm* alloc_heap_heavy(ErlNifEnv* env, size_t need, Eterm* hp);
static ERTS_INLINE int
is_scheduler(void)
@@ -135,7 +135,7 @@ execution_state(ErlNifEnv *env, Process **c_pp, int *schedp)
}
}
-static ERTS_INLINE Eterm* alloc_heap(ErlNifEnv* env, unsigned need)
+static ERTS_INLINE Eterm* alloc_heap(ErlNifEnv* env, size_t need)
{
Eterm* hp = env->hp;
env->hp += need;
@@ -145,7 +145,7 @@ static ERTS_INLINE Eterm* alloc_heap(ErlNifEnv* env, unsigned need)
return alloc_heap_heavy(env, need, hp);
}
-static Eterm* alloc_heap_heavy(ErlNifEnv* env, unsigned need, Eterm* hp)
+static Eterm* alloc_heap_heavy(ErlNifEnv* env, size_t need, Eterm* hp)
{
env->hp = hp;
if (env->heap_frag == NULL) {
@@ -166,7 +166,7 @@ static Eterm* alloc_heap_heavy(ErlNifEnv* env, unsigned need, Eterm* hp)
}
#if SIZEOF_LONG != ERTS_SIZEOF_ETERM
-static ERTS_INLINE void ensure_heap(ErlNifEnv* env, unsigned may_need)
+static ERTS_INLINE void ensure_heap(ErlNifEnv* env, size_t may_need)
{
if (env->hp + may_need > env->hp_end) {
alloc_heap_heavy(env, may_need, env->hp);
@@ -667,6 +667,9 @@ int enif_send(ErlNifEnv* env, const ErlNifPid* to_pid,
erts_smp_proc_trylock(rp, ERTS_PROC_LOCK_MSGQ) == EBUSY) {
if (!msgq) {
+#ifdef ERTS_SMP
+ ErtsThrPrgrDelayHandle dhndl;
+#endif
msgq = erts_alloc(ERTS_ALC_T_TRACE_MSG_QUEUE,
sizeof(ErlTraceMessageQueue));
@@ -681,8 +684,15 @@ int enif_send(ErlNifEnv* env, const ErlNifPid* to_pid,
erts_smp_proc_unlock(t_p, ERTS_PROC_LOCK_TRACE);
+#ifdef ERTS_SMP
+ if (!scheduler)
+ dhndl = erts_thr_progress_unmanaged_delay();
+#endif
erts_schedule_flush_trace_messages(t_p->common.id);
-
+#ifdef ERTS_SMP
+ if (!scheduler)
+ erts_thr_progress_unmanaged_continue(dhndl);
+#endif
} else {
msgq->len++;
*msgq->last = mp;
@@ -1197,7 +1207,7 @@ Eterm enif_make_sub_binary(ErlNifEnv* env, ERL_NIF_TERM bin_term,
Eterm orig;
Uint offset, bit_offset, bit_size;
#ifdef DEBUG
- unsigned src_size;
+ size_t src_size;
ASSERT(is_binary(bin_term));
src_size = binary_size(bin_term);
@@ -1669,7 +1679,8 @@ int enif_is_process_alive(ErlNifEnv* env, ErlNifPid *proc)
return !!rp;
#else
erts_exit(ERTS_ABORT_EXIT, "enif_is_process_alive: "
- "called from non-scheduler thread");
+ "called from non-scheduler thread "
+ "in non-smp emulator");
return 0;
#endif
}
@@ -1694,7 +1705,8 @@ int enif_is_port_alive(ErlNifEnv *env, ErlNifPort *port)
return !!prt;
#else
erts_exit(ERTS_ABORT_EXIT, "enif_is_port_alive: "
- "called from non-scheduler thread");
+ "called from non-scheduler thread "
+ "in non-smp emulator");
return 0;
#endif
}
diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h
index 2801947613..b44ac442aa 100644
--- a/erts/emulator/beam/erl_process.h
+++ b/erts/emulator/beam/erl_process.h
@@ -960,7 +960,6 @@ struct process {
Uint heap_sz; /* Size of heap in words */
Uint min_heap_size; /* Minimum size of heap (in words). */
Uint min_vheap_size; /* Minimum size of virtual heap (in words). */
- Uint max_heap_size; /* Maximum size of heap (in words). */
#if !defined(NO_FPE_SIGNALS) || defined(HIPE)
volatile unsigned long fp_exception;
@@ -1061,6 +1060,7 @@ struct process {
Eterm *old_hend; /* Heap pointers for generational GC. */
Eterm *old_htop;
Eterm *old_heap;
+ Uint max_heap_size; /* Maximum size of heap (in words). */
Uint16 gen_gcs; /* Number of (minor) generational GCs. */
Uint16 max_gen_gcs; /* Max minor gen GCs before fullsweep. */
ErlOffHeap off_heap; /* Off-heap data updated by copy_struct(). */
@@ -1339,7 +1339,7 @@ ERTS_GLB_INLINE void erts_heap_frag_shrink(Process* p, Eterm* hp)
{
ErlHeapFragment* hf = MBUF(p);
- ASSERT(hf!=NULL && (hp - hf->mem < (unsigned long)hf->alloc_size));
+ ASSERT(hf!=NULL && (hp - hf->mem < hf->alloc_size));
hf->used_size = hp - hf->mem;
}
diff --git a/erts/emulator/beam/erl_unicode.c b/erts/emulator/beam/erl_unicode.c
index 3c3536c021..bd5e1482fb 100644
--- a/erts/emulator/beam/erl_unicode.c
+++ b/erts/emulator/beam/erl_unicode.c
@@ -55,7 +55,7 @@ static BIF_RETTYPE finalize_list_to_list(Process *p,
Uint num_processed_bytes,
Uint num_bytes_to_process,
Uint num_resulting_chars,
- int state, int left,
+ int state, Sint left,
Eterm tail);
static BIF_RETTYPE characters_to_utf8_trap(BIF_ALIST_3);
static BIF_RETTYPE characters_to_list_trap_1(BIF_ALIST_3);
@@ -173,12 +173,13 @@ static ERTS_INLINE int allowed_iterations(Process *p)
else
return tmp;
}
-static ERTS_INLINE int cost_to_proc(Process *p, int cost)
+
+static ERTS_INLINE void cost_to_proc(Process *p, Sint cost)
{
- int x = (cost / LOOP_FACTOR);
+ Sint x = (cost / LOOP_FACTOR);
BUMP_REDS(p,x);
- return x;
}
+
static ERTS_INLINE int simple_loops_to_common(int cost)
{
int factor = (LOOP_FACTOR_SIMPLE / LOOP_FACTOR);
@@ -243,14 +244,15 @@ static int utf8_len(byte first)
return -1;
}
-static int copy_utf8_bin(byte *target, byte *source, Uint size,
- byte *leftover, int *num_leftovers,
- byte **err_pos, Uint *characters) {
- int copied = 0;
+static Uint copy_utf8_bin(byte *target, byte *source, Uint size,
+ byte *leftover, int *num_leftovers,
+ byte **err_pos, Uint *characters)
+{
+ Uint copied = 0;
if (leftover != NULL && *num_leftovers) {
int need = utf8_len(leftover[0]);
int from_source = need - (*num_leftovers);
- int c;
+ Uint c;
byte *tmp_err_pos = NULL;
ASSERT(need > 0);
ASSERT(from_source > 0);
@@ -502,8 +504,8 @@ L_Again: /* Restart with sublist, old listend was pushed on stack */
}
-static Eterm do_build_utf8(Process *p, Eterm ioterm, int *left, int latin1,
- byte *target, int *pos, Uint *characters, int *err,
+static Eterm do_build_utf8(Process *p, Eterm ioterm, Sint *left, int latin1,
+ byte *target, Uint *pos, Uint *characters, int *err,
byte *leftover, int *num_leftovers)
{
int c;
@@ -573,7 +575,7 @@ static Eterm do_build_utf8(Process *p, Eterm ioterm, int *left, int latin1,
}
if (!latin1) {
- int num;
+ Uint num;
byte *err_pos = NULL;
num = copy_utf8_bin(target + (*pos), bytes,
size, leftover, num_leftovers,&err_pos,characters);
@@ -804,7 +806,7 @@ static int check_leftovers(byte *source, int size)
-static BIF_RETTYPE build_utf8_return(Process *p,Eterm bin,int pos,
+static BIF_RETTYPE build_utf8_return(Process *p,Eterm bin,Uint pos,
Eterm rest_term,int err,
byte *leftover,int num_leftovers,Eterm latin1)
{
@@ -859,8 +861,8 @@ static BIF_RETTYPE characters_to_utf8_trap(BIF_ALIST_3)
#endif
byte* bytes;
Eterm rest_term;
- int left, sleft;
- int pos;
+ Sint left, sleft;
+ Uint pos;
int err;
byte leftover[4]; /* used for temp buffer too,
otherwise 3 bytes would have been enough */
@@ -874,7 +876,7 @@ static BIF_RETTYPE characters_to_utf8_trap(BIF_ALIST_3)
real_bin = binary_val(BIF_ARG_1);
ASSERT(*real_bin == HEADER_PROC_BIN);
#endif
- pos = (int) binary_size(BIF_ARG_1);
+ pos = binary_size(BIF_ARG_1);
bytes = binary_bytes(BIF_ARG_1);
sleft = left = allowed_iterations(BIF_P);
err = 0;
@@ -934,9 +936,9 @@ BIF_RETTYPE unicode_characters_to_binary_2(BIF_ALIST_2)
int latin1;
Eterm bin;
byte *bytes;
- int pos;
+ Uint pos;
int err;
- int left, sleft;
+ Sint left, sleft;
Eterm rest_term, subject;
byte leftover[4]; /* used for temp buffer too, o
therwise 3 bytes would have been enough */
@@ -999,7 +1001,7 @@ BIF_RETTYPE unicode_characters_to_binary_2(BIF_ALIST_2)
byte *t = NULL;
Uint sz = binary_size(bin);
byte *by = erts_get_aligned_binary_bytes(bin,&t);
- int i;
+ Uint i;
erts_printf("<<");
for (i = 0;i < sz; ++i) {
erts_printf((i == sz -1) ? "0x%X" : "0x%X, ", (unsigned) by[i]);
@@ -1007,7 +1009,7 @@ BIF_RETTYPE unicode_characters_to_binary_2(BIF_ALIST_2)
erts_printf(">>: ");
erts_free_aligned_binary_bytes(t);
}
- erts_printf("%d - %d = %d\n",sleft,left,sleft - left);
+ erts_printf("%ld - %ld = %ld\n", sleft, left, sleft - left);
}
#endif
cost_to_proc(BIF_P, sleft - left);
@@ -1015,10 +1017,10 @@ BIF_RETTYPE unicode_characters_to_binary_2(BIF_ALIST_2)
leftover,num_leftovers,BIF_ARG_2);
}
-static BIF_RETTYPE build_list_return(Process *p, byte *bytes, int pos, Uint characters,
+static BIF_RETTYPE build_list_return(Process *p, byte *bytes, Uint pos, Uint characters,
Eterm rest_term, int err,
byte *leftover, int num_leftovers,
- Eterm latin1, int left)
+ Eterm latin1, Sint left)
{
Eterm *hp;
@@ -1070,11 +1072,11 @@ static BIF_RETTYPE characters_to_list_trap_1(BIF_ALIST_3)
{
RestartContext *rc;
byte* bytes;
- int pos;
+ Uint pos;
Uint characters;
int err;
Eterm rest_term;
- int left, sleft;
+ Sint left, sleft;
int latin1 = 0;
byte leftover[4]; /* used for temp buffer too,
@@ -1107,9 +1109,9 @@ BIF_RETTYPE unicode_characters_to_list_2(BIF_ALIST_2)
int latin1;
Uint characters = 0;
byte *bytes;
- int pos;
+ Uint pos;
int err;
- int left, sleft;
+ Sint left, sleft;
Eterm rest_term;
byte leftover[4]; /* used for temp buffer too, o
therwise 3 bytes would have been enough */
@@ -1541,7 +1543,7 @@ static BIF_RETTYPE finalize_list_to_list(Process *p,
Uint num_processed_bytes,
Uint num_bytes_to_process,
Uint num_resulting_chars,
- int state, int left,
+ int state, Sint left,
Eterm tail)
{
Uint num_built; /* characters */
@@ -2016,7 +2018,7 @@ char *erts_convert_filename_to_encoding(Eterm name, char *statbuf, size_t statbu
++need;
}
if (used)
- *used = (Sint) need;
+ *used = need;
if (need+extra > statbuf_size) {
name_buf = (char *) erts_alloc(alloc_type, need+extra);
} else {
diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h
index 1abcc6cbf4..b76b9cd874 100644
--- a/erts/emulator/beam/global.h
+++ b/erts/emulator/beam/global.h
@@ -947,7 +947,7 @@ ERTS_GLB_INLINE Eterm erts_equeue_get(ErtsEQueue *q) {
void erts_emasculate_writable_binary(ProcBin* pb);
Eterm erts_new_heap_binary(Process *p, byte *buf, int len, byte** datap);
-Eterm erts_new_mso_binary(Process*, byte*, int);
+Eterm erts_new_mso_binary(Process*, byte*, Uint);
Eterm new_binary(Process*, byte*, Uint);
Eterm erts_realloc_binary(Eterm bin, size_t size);
diff --git a/erts/emulator/hipe/hipe_mode_switch.c b/erts/emulator/hipe/hipe_mode_switch.c
index f532d3151f..884331e969 100644
--- a/erts/emulator/hipe/hipe_mode_switch.c
+++ b/erts/emulator/hipe/hipe_mode_switch.c
@@ -174,6 +174,33 @@ void hipe_mode_switch_init(void)
make_catch(beam_catches_cons(hipe_beam_pc_throw, BEAM_CATCHES_NIL));
hipe_mfa_info_table_init();
+
+#if (defined(__i386__) || defined(__x86_64__)) && defined(__linux__)
+ /* Verify that the offset of c-p->hipe does not change.
+ The ErLLVM hipe backend depends on it being in a specific
+ position. Kostis et al has promised to fix this in upstream
+ llvm by OTP 20, so it should be possible to remove these asserts
+ after that. */
+ ERTS_CT_ASSERT(sizeof(ErtsPTabElementCommon) ==
+ (sizeof(Eterm) + /* id */
+ sizeof(((ErtsPTabElementCommon*)0)->refc) +
+ sizeof(ErtsTracer) + /* tracer */
+ sizeof(Uint) + /* trace_flags */
+ sizeof(erts_smp_atomic_t) + /* timer */
+ sizeof(((ErtsPTabElementCommon*)0)->u)));
+
+ ERTS_CT_ASSERT(offsetof(Process, hipe) ==
+ (sizeof(ErtsPTabElementCommon) + /* common */
+ sizeof(Eterm*) + /* htop */
+ sizeof(Eterm*) + /* stop */
+ sizeof(Eterm*) + /* heap */
+ sizeof(Eterm*) + /* hend */
+ sizeof(Uint) + /* heap_sz */
+ sizeof(Uint) + /* min_heap_size */
+ sizeof(Uint) + /* min_vheap_size */
+ sizeof(volatile unsigned long))); /* fp_exception */
+#endif
+
}
void hipe_set_call_trap(Uint *bfun, void *nfun, int is_closure)
diff --git a/erts/emulator/test/alloc_SUITE.erl b/erts/emulator/test/alloc_SUITE.erl
index 1f7b499dcb..84cf4921d3 100644
--- a/erts/emulator/test/alloc_SUITE.erl
+++ b/erts/emulator/test/alloc_SUITE.erl
@@ -73,16 +73,32 @@ migration(Cfg) ->
end.
erts_mmap(Config) when is_list(Config) ->
- case os:type() of
- {unix, _} ->
+ case {os:type(), mmsc_flags()} of
+ {{unix,_}, false} ->
[erts_mmap_do(Config, SCO, SCRPM, SCRFSD)
|| SCO <-[true,false], SCRFSD <-[1234,0], SCRPM <- [true,false]];
- {SkipOs,_} ->
+ {{unix,_}, Flags} ->
+ {skipped, Flags};
+ {{SkipOs,_},_} ->
{skipped,
lists:flatten(["Not run on "
| io_lib:format("~p",[SkipOs])])}
end.
+%% Check if there are ERL_FLAGS set that will mess up this test case
+mmsc_flags() ->
+ case mmsc_flags("ERL_FLAGS") of
+ false -> mmsc_flags("ERL_ZFLAGS");
+ Flags -> Flags
+ end.
+mmsc_flags(Env) ->
+ case os:getenv(Env) of
+ false -> false;
+ V -> case string:str(V, "+MMsc") of
+ 0 -> false;
+ P -> Env ++ "=" ++ string:substr(V, P)
+ end
+ end.
erts_mmap_do(Config, SCO, SCRPM, SCRFSD) ->
%% We use the number of schedulers + 1 * approx main carriers size
diff --git a/erts/emulator/test/port_trace_SUITE.erl b/erts/emulator/test/port_trace_SUITE.erl
index bfdea0761b..5d9a75bcd3 100644
--- a/erts/emulator/test/port_trace_SUITE.erl
+++ b/erts/emulator/test/port_trace_SUITE.erl
@@ -31,7 +31,8 @@
failure_atom/1, failure_posix/1,
failure/1, output_term/1,
driver_output_term/1,
- send_term/1, driver_send_term/1]).
+ send_term/1, driver_send_term/1,
+ driver_remote_send_term/1]).
-define(ECHO_DRV_NOOP, 0).
-define(ECHO_DRV_OUTPUT, 1).
@@ -48,6 +49,7 @@
-define(ECHO_DRV_SEND_TERM, 12).
-define(ECHO_DRV_DRIVER_SEND_TERM, 13).
-define(ECHO_DRV_SAVE_CALLER, 14).
+-define(ECHO_DRV_REMOTE_SEND_TERM, 15).
suite() -> [{ct_hooks,[ts_install_cth]},
{timetrap, {seconds, 30}}].
@@ -60,7 +62,8 @@ all() ->
failure_atom, failure_posix,
failure, output_term,
driver_output_term,
- send_term, driver_send_term].
+ send_term, driver_send_term,
+ driver_remote_send_term].
init_per_suite(Config) ->
Config.
@@ -75,6 +78,13 @@ end_per_group(_GroupName, Config) ->
Config.
+init_per_testcase(driver_remote_send_term, Config) ->
+ case erlang:system_info(smp_support) of
+ false ->
+ {skip,"Only supported on smp systems"};
+ true ->
+ init_per_testcase(driver_remote_send_term_smp, Config)
+ end;
init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
erlang:trace(all, false, [all]),
os:unsetenv("OUTPUTV"),
@@ -543,6 +553,34 @@ driver_send_term(_Config) ->
ok.
+%% Test that driver_send_term from non-scheduler thread does not
+%% generate trace messages.
+driver_remote_send_term(_Config) ->
+
+ Flags = [send],
+ {Prt, S} = trace_and_open(Flags,[binary]),
+
+ erlang:port_command(Prt, <<?ECHO_DRV_REMOTE_SEND_TERM, 123456:32>>),
+ recv({echo, Prt, <<123456:32>>}),
+ [] = flush(),
+
+ Pid = spawn_link(
+ fun() ->
+ erlang:port_command(Prt, <<?ECHO_DRV_SAVE_CALLER>>),
+ S ! ok,
+ receive M -> S ! M end
+ end),
+ recv(ok),
+ erlang:trace(Pid, true, ['receive']),
+
+ erlang:port_command(Prt, <<?ECHO_DRV_REMOTE_SEND_TERM, 123456:32>>),
+ recv({echo, Prt, <<123456:32>>}),
+ [{trace, Pid, 'receive', {echo, Prt, <<123456:32>>}}] = flush(),
+
+ close(Prt, Flags),
+
+ ok.
+
%%%%%%%%%%%%%%%%%%%
%% Helper functions
%%%%%%%%%%%%%%%%%%%
@@ -598,7 +636,7 @@ f(From) ->
end.
recv(Msg) ->
- receive Msg -> ok after 100 -> ct:fail({did_not_get_data,Msg,flush()}) end.
+ receive Msg -> ok after 1000 -> ct:fail({did_not_get_data,Msg,flush()}) end.
load_drv(Config) ->
Path = proplists:get_value(data_dir, Config),
diff --git a/erts/emulator/test/port_trace_SUITE_data/echo_drv.c b/erts/emulator/test/port_trace_SUITE_data/echo_drv.c
index b5ae9389b4..b545523192 100644
--- a/erts/emulator/test/port_trace_SUITE_data/echo_drv.c
+++ b/erts/emulator/test/port_trace_SUITE_data/echo_drv.c
@@ -14,6 +14,13 @@ typedef struct _erl_drv_data {
ErlDrvTermData caller;
} EchoDrvData;
+struct remote_send_term {
+ char *buf;
+ int len;
+ ErlDrvTermData port;
+ ErlDrvTermData caller;
+};
+
#define ECHO_DRV_NOOP 0
#define ECHO_DRV_OUTPUT 1
#define ECHO_DRV_OUTPUT2 2
@@ -29,6 +36,7 @@ typedef struct _erl_drv_data {
#define ECHO_DRV_SEND_TERM 12
#define ECHO_DRV_DRIVER_SEND_TERM 13
#define ECHO_DRV_SAVE_CALLER 14
+#define ECHO_DRV_REMOTE_SEND_TERM 15
/* -------------------------------------------------------------------------
@@ -78,6 +86,8 @@ static ErlDrvEntry echo_drv_entry = {
NULL
};
+static void send_term_thread(void *);
+
/* -------------------------------------------------------------------------
** Entry functions
**/
@@ -200,6 +210,18 @@ static void echo_drv_output(ErlDrvData drv_data, char *buf, ErlDrvSizeT len) {
}
break;
}
+ case ECHO_DRV_REMOTE_SEND_TERM:
+ {
+ ErlDrvTid tid;
+ struct remote_send_term *t = malloc(sizeof(struct remote_send_term));
+ t->len = len-1;
+ t->buf = malloc(len-1);
+ t->port = driver_mk_port(port);
+ t->caller = data_p->caller;
+ memcpy(t->buf, buf+1, t->len);
+ erl_drv_thread_create("tmp_thread", &tid, send_term_thread, t, NULL);
+ break;
+ }
case ECHO_DRV_SAVE_CALLER:
data_p->caller = driver_caller(port);
break;
@@ -239,3 +261,17 @@ static ErlDrvSSizeT echo_drv_call(ErlDrvData drv_data,
memcpy(*rbuf, buf+command, len-command);
return len-command;
}
+
+static void send_term_thread(void *a)
+{
+ struct remote_send_term *t = (struct remote_send_term*)a;
+ ErlDrvTermData term[] = {
+ ERL_DRV_ATOM, driver_mk_atom("echo"),
+ ERL_DRV_PORT, t->port,
+ ERL_DRV_BUF2BINARY, (ErlDrvTermData)(t->buf),
+ (ErlDrvTermData)(t->len),
+ ERL_DRV_TUPLE, 3};
+ erl_drv_send_term(t->port, t->caller,
+ term, sizeof(term) / sizeof(ErlDrvTermData));
+ return;
+}
diff --git a/erts/emulator/test/time_SUITE.erl b/erts/emulator/test/time_SUITE.erl
index 76d440529f..87b8c62cfa 100644
--- a/erts/emulator/test/time_SUITE.erl
+++ b/erts/emulator/test/time_SUITE.erl
@@ -209,23 +209,17 @@ test_seconds_to_univ([]) ->
%% Test that the the different time functions return
-%% consistent results. (See the test case for assumptions
-%% and limitations.)
-consistency(Config) when is_list(Config) ->
- %% Test the following equations:
- %% date() & time() == erlang:localtime()
- %% erlang:universaltime() + timezone == erlang:localtime()
+%% consistent results.
+consistency(_Config) ->
+ %% Test that:
+ %% * date() & time() gives the same time as erlang:localtime()
%%
- %% Assumptions:
- %% Middle-European time zone, EU rules for daylight-saving time.
- %%
- %% Limitations:
- %% Localtime and universaltime must be in the same month.
- %% Daylight-saving calculations are incorrect from the last
- %% Sunday of March and October to the end of the month.
+ %% * the difference between erlang:universaltime() and
+ %% erlang:localtime() is reasonable (with assuming any
+ %% particular timezone)
ok = compare_date_time_and_localtime(16),
- ok = compare_local_and_universal(16).
+ compare_local_and_universal(16).
compare_date_time_and_localtime(Times) when Times > 0 ->
{Year, Mon, Day} = date(),
@@ -238,22 +232,18 @@ compare_date_time_and_localtime(0) ->
error.
compare_local_and_universal(Times) when Times > 0 ->
- case compare(erlang:universaltime(), erlang:localtime()) of
- true -> ok;
- false -> compare_local_and_universal(Times-1)
- end;
-compare_local_and_universal(0) ->
- error.
+ Utc = erlang:universaltime(),
+ Local = erlang:localtime(),
+ io:format("local = ~p, utc = ~p", [Local,Utc]),
-compare(Utc0, Local) ->
- io:format("local = ~p, utc = ~p", [Local, Utc0]),
- Utc = linear_time(Utc0)+effective_timezone(Utc0)*3600,
- case linear_time(Local) of
- Utc -> true;
- Other ->
- io:format("Failed: local = ~p, utc = ~p~n",
- [Other, Utc]),
- false
+ AcceptableDiff = 14*3600,
+ case linear_time(Utc) - linear_time(Local) of
+ Diff when abs(Diff) < AcceptableDiff ->
+ ok;
+ Diff ->
+ io:format("More than ~p seconds difference betwen "
+ "local and universal time", [Diff]),
+ ct:fail(huge_diff)
end.
%% This function converts a date and time to a linear time.
@@ -280,35 +270,6 @@ days_in_february(Year) ->
_ -> 28
end.
-%% This functions returns either the normal timezone or the
-%% the DST timezone, depending on the given UTC time.
-%%
-%% XXX This function uses an approximation of the EU rule for
-%% daylight saving time. This function will fail in the
-%% following intervals: After the last Sunday in March upto
-%% the end of March, and after the last Sunday in October
-%% upto the end of October.
-
-effective_timezone(Time) ->
- case os:type() of
- {unix,_} ->
- case os:cmd("date '+%Z'") of
- "SAST"++_ ->
- 2;
- _ ->
- effective_timezone1(Time)
- end;
- _ ->
- effective_timezone1(Time)
- end.
-
-effective_timezone1({{_Year,Mon,_Day}, _}) when Mon < 4 ->
- ?timezone;
-effective_timezone1({{_Year,Mon,_Day}, _}) when Mon > 10 ->
- ?timezone;
-effective_timezone1(_) ->
- ?dst_timezone.
-
%% Test (the bif) os:timestamp/0, which is something quite like, but not
%% similar to erlang:now...
diff --git a/erts/preloaded/ebin/erl_prim_loader.beam b/erts/preloaded/ebin/erl_prim_loader.beam
index de2693472a..66e443f396 100644
--- a/erts/preloaded/ebin/erl_prim_loader.beam
+++ b/erts/preloaded/ebin/erl_prim_loader.beam
Binary files differ
diff --git a/erts/preloaded/src/erl_prim_loader.erl b/erts/preloaded/src/erl_prim_loader.erl
index e18e187cb7..b3ec73a60e 100644
--- a/erts/preloaded/src/erl_prim_loader.erl
+++ b/erts/preloaded/src/erl_prim_loader.erl
@@ -558,11 +558,9 @@ efile_gm_get_1([P|Ps], File0, Mod, {Parent,Ref}=PR, Process) ->
Res = try prim_file:read_file(File) of
{ok,Bin} ->
gm_process(Mod, File, Bin, Process);
- {error,enoent} ->
- efile_gm_get_1(Ps, File0, Mod, PR, Process);
Error ->
- check_file_result(get_modules, File, Error),
- Error
+ _ = check_file_result(get_modules, File, Error),
+ efile_gm_get_1(Ps, File0, Mod, PR, Process)
catch
_:Reason ->
{error,{crash,Reason}}
diff --git a/lib/common_test/doc/src/ct_netconfc.xml b/lib/common_test/doc/src/ct_netconfc.xml
index 9d1ff25a3a..e6930b30d5 100644
--- a/lib/common_test/doc/src/ct_netconfc.xml
+++ b/lib/common_test/doc/src/ct_netconfc.xml
@@ -201,7 +201,8 @@
information, see module <seealso marker="ct"><c>ct</c></seealso>.</p>
</item>
- <tag><c>host() = <seealso marker="kernel:inet#type-hostname"><c>inet:hostname()</c></seealso> | <seealso marker="kernel:inet#type-ip_address"><c>inet:ip_address()</c></seealso></c></tag>
+ <tag><c>host() = </c><seealso marker="kernel:inet#type-hostname"><c>inet:hostname()</c></seealso>
+ <c> | </c><seealso marker="kernel:inet#type-ip_address"><c>inet:ip_address()</c></seealso></tag>
<item><marker id="type-host"/></item>
<tag><c>key_or_name() = server_id() | target_name()</c></tag>
@@ -218,7 +219,9 @@
<tag><c>notification_content() = [event_time() | simple_xml()]</c></tag>
<item><marker id="type-notification_content"/> </item>
- <tag><c>option() = {ssh, host()} | {port, <seealso marker="kernel:inet#type-port_number"><c>inet:port_number()</c></seealso>} | {timeout, timeout()} | SshConnectOption</c></tag>
+ <tag><c>option() = {ssh, host()} | {port, </c>
+ <seealso marker="kernel:inet#type-port_number"><c>inet:port_number()</c></seealso>
+ <c>} | {timeout, timeout()} | SshConnectOption</c></tag>
<item><marker id="type-option"/>
<p><c>SshConnectOption</c> is any valid option to
diff --git a/lib/compiler/src/beam_bool.erl b/lib/compiler/src/beam_bool.erl
index f9a08f8718..359fdb6d3c 100644
--- a/lib/compiler/src/beam_bool.erl
+++ b/lib/compiler/src/beam_bool.erl
@@ -238,9 +238,9 @@ extend_block(BlAcc0, Fail, [{block,Is0}|OldAcc]) ->
end;
extend_block(BlAcc, _, OldAcc) -> {BlAcc,OldAcc}.
-extend_block_1([{set,[_],_,{bif,_,{f,Fail}}}=I|Is], Fail, Acc) ->
+extend_block_1([{set,[{x,_}],_,{bif,_,{f,Fail}}}=I|Is], Fail, Acc) ->
extend_block_1(Is, Fail, [I|Acc]);
-extend_block_1([{set,[_],As,{bif,Bif,_}}=I|Is]=Is0, Fail, Acc) ->
+extend_block_1([{set,[{x,_}],As,{bif,Bif,_}}=I|Is]=Is0, Fail, Acc) ->
case safe_bool_op(Bif, length(As)) of
false -> {Acc,reverse(Is0)};
true -> extend_block_1(Is, Fail, [I|Acc])
diff --git a/lib/compiler/src/beam_utils.erl b/lib/compiler/src/beam_utils.erl
index 37f89dd677..47703b4aa3 100644
--- a/lib/compiler/src/beam_utils.erl
+++ b/lib/compiler/src/beam_utils.erl
@@ -25,9 +25,8 @@
is_not_used/3,is_not_used_at/3,
empty_label_index/0,index_label/3,index_labels/1,
code_at/2,bif_to_test/3,is_pure_test/1,
- live_opt/1,delete_live_annos/1,combine_heap_needs/2]).
-
--export([join_even/2,split_even/1]).
+ live_opt/1,delete_live_annos/1,combine_heap_needs/2,
+ join_even/2,split_even/1]).
-import(lists, [member/2,sort/1,reverse/1,splitwith/2]).
@@ -67,8 +66,7 @@ is_killed(R, Is, D) ->
St = #live{bl=check_killed_block_fun(),lbl=D,res=gb_trees:empty()},
case check_liveness(R, Is, St) of
{killed,_} -> true;
- {used,_} -> false;
- {unknown,_} -> false
+ {used,_} -> false
end.
%% is_killed_at(Reg, Lbl, State) -> true|false
@@ -78,8 +76,7 @@ is_killed_at(R, Lbl, D) when is_integer(Lbl) ->
St0 = #live{bl=check_killed_block_fun(),lbl=D,res=gb_trees:empty()},
case check_liveness_at(R, Lbl, St0) of
{killed,_} -> true;
- {used,_} -> false;
- {unknown,_} -> false
+ {used,_} -> false
end.
%% is_not_used(Register, [Instruction], State) -> true|false
@@ -93,8 +90,7 @@ is_not_used(R, Is, D) ->
St = #live{bl=fun check_used_block/3,lbl=D,res=gb_trees:empty()},
case check_liveness(R, Is, St) of
{killed,_} -> true;
- {used,_} -> false;
- {unknown,_} -> false
+ {used,_} -> false
end.
%% is_not_used(Register, [Instruction], State) -> true|false
@@ -108,8 +104,7 @@ is_not_used_at(R, Lbl, D) ->
St = #live{bl=fun check_used_block/3,lbl=D,res=gb_trees:empty()},
case check_liveness_at(R, Lbl, St) of
{killed,_} -> true;
- {used,_} -> false;
- {unknown,_} -> false
+ {used,_} -> false
end.
%% index_labels(FunctionIs) -> State
@@ -137,10 +132,7 @@ index_label(Lbl, Is0, Acc) ->
%% Retrieve the code at the given label.
code_at(L, Ll) ->
- case gb_trees:lookup(L, Ll) of
- {value,Code} -> Code;
- none -> none
- end.
+ gb_trees:get(L, Ll).
%% bif_to_test(Bif, [Op], Fail) -> {test,Test,Fail,[Op]}
%% Convert a BIF to a test. Fail if not possible.
@@ -164,10 +156,10 @@ bif_to_test('=<', [A,B], Fail) -> {test,is_ge,Fail,[B,A]};
bif_to_test('>', [A,B], Fail) -> {test,is_lt,Fail,[B,A]};
bif_to_test('<', [_,_]=Ops, Fail) -> {test,is_lt,Fail,Ops};
bif_to_test('>=', [_,_]=Ops, Fail) -> {test,is_ge,Fail,Ops};
-bif_to_test('==', [A,[]], Fail) -> {test,is_nil,Fail,[A]};
+bif_to_test('==', [A,nil], Fail) -> {test,is_nil,Fail,[A]};
bif_to_test('==', [_,_]=Ops, Fail) -> {test,is_eq,Fail,Ops};
bif_to_test('/=', [_,_]=Ops, Fail) -> {test,is_ne,Fail,Ops};
-bif_to_test('=:=', [A,[]], Fail) -> {test,is_nil,Fail,[A]};
+bif_to_test('=:=', [A,nil], Fail) -> {test,is_nil,Fail,[A]};
bif_to_test('=:=', [_,_]=Ops, Fail) -> {test,is_eq_exact,Fail,Ops};
bif_to_test('=/=', [_,_]=Ops, Fail) -> {test,is_ne_exact,Fail,Ops};
bif_to_test(is_record, [_,_,_]=Ops, Fail) -> {test,is_record,Fail,Ops}.
@@ -235,21 +227,28 @@ combine_heap_needs(Words, {alloc,Alloc}) when is_integer(Words) ->
combine_heap_needs(H1, H2) when is_integer(H1), is_integer(H2) ->
H1+H2.
+%% split_even/1
+%% [1,2,3,4,5,6] -> {[1,3,5],[2,4,6]}
+
+split_even(Rs) -> split_even(Rs, [], []).
+
+%% join_even/1
+%% {[1,3,5],[2,4,6]} -> [1,2,3,4,5,6]
+
+join_even([], []) -> [];
+join_even([S|Ss], [D|Ds]) -> [S,D|join_even(Ss, Ds)].
+
%%%
%%% Local functions.
%%%
-%% check_liveness(Reg, [Instruction], {State,BlockCheckFun}) ->
-%% {killed | used | unknown,UpdateState}
-%% Finds out how Reg is used in the instruction sequence. Returns one of:
-%% killed - Reg is assigned a new value or killed by an allocation instruction
-%% used - Reg is used (or possibly referenced by an allocation instruction)
-%% unknown - not possible to determine (perhaps because of an instruction
-%% that we don't recognize)
+%% check_liveness(Reg, [Instruction], #live{}) ->
+%% {killed | used, #live{}}
+%% Find out whether Reg is used or killed in instruction sequence.
+%% 'killed' means that Reg is assigned a new value or killed by an
+%% allocation instruction. 'used' means that Reg is used in some way.
-check_liveness(R, [{set,_,_,_}=I|_], St) ->
- erlang:error(only_allowed_in_blocks, [R,I,St]);
check_liveness(R, [{block,Blk}|Is], #live{bl=BlockCheck}=St0) ->
case BlockCheck(R, Blk, St0) of
{transparent,St} -> check_liveness(R, Is, St);
@@ -461,8 +460,9 @@ check_liveness(R, [{loop_rec,{f,_},{x,0}}|_], St) ->
{x,_} ->
{killed,St};
_ ->
- %% y register. Rarely happens. Be very conversative.
- {unknown,St}
+ %% y register. Rarely happens. Be very conversative and
+ %% assume it's used.
+ {used,St}
end;
check_liveness(R, [{loop_rec_end,{f,Fail}}|_], St) ->
check_liveness_at(R, Fail, St);
@@ -493,7 +493,8 @@ check_liveness(R, [{put_map,{f,_},_,Src,_D,Live,{list,_}}|_], St0) ->
{x,_} ->
{killed,St0};
{y,_} ->
- {unknown,St0}
+ %% Conservatively mark it as used.
+ {used,St0}
end;
check_liveness(R, [{test_heap,N,Live}|Is], St) ->
I = {block,[{set,[],[],{alloc,Live,{nozero,nostack,N,[]}}}]},
@@ -505,12 +506,8 @@ check_liveness(R, [{get_list,S,D1,D2}|Is], St) ->
I = {block,[{set,[D1,D2],[S],get_list}]},
check_liveness(R, [I|Is], St);
check_liveness(_R, Is, St) when is_list(Is) ->
-%% case Is of
-%% [I|_] ->
-%% io:format("~p ~p\n", [_R,I]);
-%% _ -> ok
-%% end,
- {unknown,St}.
+ %% Not implemented. Conservatively assume that the register is used.
+ {used,St}.
check_liveness_everywhere(R, [{f,Lbl}|T], St0) ->
case check_liveness_at(R, Lbl, St0) of
@@ -529,7 +526,7 @@ check_liveness_at(R, Lbl, #live{lbl=Ll,res=ResMemorized}=St0) ->
none ->
{Res,St} = case gb_trees:lookup(Lbl, Ll) of
{value,Is} -> check_liveness(R, Is, St0);
- none -> {unknown,St0}
+ none -> {used,St0}
end,
{Res,St#live{res=gb_trees:insert(Lbl, Res, St#live.res)}}
end.
@@ -594,8 +591,10 @@ check_killed_block(_, []) -> transparent.
%% killed - Reg is assigned a new value or killed by an allocation instruction
%% transparent - Reg is neither used nor killed
%% used - Reg is explicitly used by an instruction
-%%
-%% (Unknown instructions will cause an exception.)
+%%
+%% '%live' annotations are not allowed.
+%%
+%% (Unknown instructions will cause an exception.)
check_used_block({x,X}=R, [{set,Ds,Ss,{alloc,Live,Op}}|Is], St) ->
if
@@ -604,11 +603,6 @@ check_used_block({x,X}=R, [{set,Ds,Ss,{alloc,Live,Op}}|Is], St) ->
end;
check_used_block(R, [{set,Ds,Ss,Op}|Is], St) ->
check_used_block_1(R, Ss, Ds, Op, Is, St);
-check_used_block(R, [{'%live',Live,_}|Is], St) ->
- case R of
- {x,X} when X >= Live -> {killed,St};
- _ -> check_used_block(R, Is, St)
- end;
check_used_block(_, [], St) -> {transparent,St}.
check_used_block_1(R, Ss, Ds, Op, Is, St0) ->
@@ -639,8 +633,7 @@ is_reg_used_at_1(_, 0, St) ->
is_reg_used_at_1(R, Lbl, St0) ->
case check_liveness_at(R, Lbl, St0) of
{killed,St} -> {false,St};
- {used,St} -> {true,St};
- {unknown,St} -> {true,St}
+ {used,St} -> {true,St}
end.
index_labels_1([{label,Lbl}|Is0], Acc) ->
@@ -756,11 +749,6 @@ live_opt([{select,_,Src,Fail,List}=I|Is], Regs0, D, Acc) ->
Regs1 = x_live([Src], Regs0),
Regs = live_join_labels([Fail|List], D, Regs1),
live_opt(Is, Regs, D, [I|Acc]);
-live_opt([{'try',_,_}=I|Is], Regs, D, Acc) ->
- %% If an exeption happens, all x registers will be killed.
- %% Therefore, we should only base liveness of the code inside
- %% the try.
- live_opt(Is, Regs, D, [I|Acc]);
live_opt([{try_case,_}=I|Is], _, D, Acc) ->
live_opt(Is, live_call(1), D, [I|Acc]);
live_opt([{loop_rec,_Fail,_Dst}=I|Is], _, D, Acc) ->
@@ -860,14 +848,7 @@ x_live([], Regs) -> Regs.
is_live(X, Regs) -> ((Regs bsr X) band 1) =:= 1.
-%% split_even/1
-%% [1,2,3,4,5,6] -> {[1,3,5],[2,4,6]}
-split_even(Rs) -> split_even(Rs,[],[]).
-split_even([],Ss,Ds) -> {reverse(Ss),reverse(Ds)};
-split_even([S,D|Rs],Ss,Ds) ->
- split_even(Rs,[S|Ss],[D|Ds]).
-
-%% join_even/1
-%% {[1,3,5],[2,4,6]} -> [1,2,3,4,5,6]
-join_even([],[]) -> [];
-join_even([S|Ss],[D|Ds]) -> [S,D|join_even(Ss,Ds)].
+split_even([], Ss, Ds) ->
+ {reverse(Ss),reverse(Ds)};
+split_even([S,D|Rs], Ss, Ds) ->
+ split_even(Rs, [S|Ss], [D|Ds]).
diff --git a/lib/compiler/src/core_pp.erl b/lib/compiler/src/core_pp.erl
index f34a5c034f..67209d06be 100644
--- a/lib/compiler/src/core_pp.erl
+++ b/lib/compiler/src/core_pp.erl
@@ -33,8 +33,7 @@
%% Prettyprint-formats (naively) an abstract Core Erlang syntax
%% tree.
--record(ctxt, {class = term :: 'clause' | 'def' | 'expr' | 'term',
- indent = 0 :: integer(),
+-record(ctxt, {indent = 0 :: integer(),
item_indent = 2 :: integer(),
body_indent = 4 :: integer(),
line = 0 :: integer(),
@@ -132,14 +131,11 @@ format_1(#c_literal{anno=A,val=Bitstring}, Ctxt) when is_bitstring(Bitstring) ->
format_1(#c_binary{anno=A,segments=Segs}, Ctxt);
format_1(#c_literal{anno=A,val=M},Ctxt) when is_map(M) ->
Pairs = maps:to_list(M),
- Op = case Ctxt of
- #ctxt{ class = clause } -> exact;
- _ -> assoc
- end,
- Cpairs = [#c_map_pair{op=#c_literal{val=Op},
+ Op = #c_literal{val=assoc},
+ Cpairs = [#c_map_pair{op=Op,
key=#c_literal{val=K},
val=#c_literal{val=V}} || {K,V} <- Pairs],
- format_1(#c_map{anno=A,arg=#c_literal{val=#{}},es=Cpairs},Ctxt);
+ format_1(#c_map{anno=A,arg=#c_literal{val=#{}},es=Cpairs},Ctxt);
format_1(#c_var{name={I,A}}, _) ->
[core_atom(I),$/,integer_to_list(A)];
format_1(#c_var{name=V}, _) ->
@@ -340,35 +336,30 @@ format_1(#c_module{name=N,exports=Es,attrs=As,defs=Ds}, Ctxt) ->
[Mod," [",
format_vseq(Es,
"", ",",
- add_indent(set_class(Ctxt, term), width(Mod, Ctxt)+2),
+ add_indent(Ctxt, width(Mod, Ctxt)+2),
fun format/2),
"]",
nl_indent(Ctxt),
" attributes [",
format_vseq(As,
"", ",",
- add_indent(set_class(Ctxt, def), 16),
+ add_indent(Ctxt, 16),
fun format_def/2),
"]",
nl_indent(Ctxt),
format_funcs(Ds, Ctxt),
nl_indent(Ctxt)
| "end"
- ];
-format_1(Type, _) ->
- ["** Unsupported type: ",
- io_lib:write(Type)
- | " **"
].
format_funcs(Fs, Ctxt) ->
format_vseq(Fs,
"", "",
- set_class(Ctxt, def),
+ Ctxt,
fun format_def/2).
format_def({N,V}, Ctxt0) ->
- Ctxt1 = add_indent(set_class(Ctxt0, expr), Ctxt0#ctxt.body_indent),
+ Ctxt1 = add_indent(Ctxt0, Ctxt0#ctxt.body_indent),
[format(N, Ctxt0),
" =",
nl_indent(Ctxt1)
@@ -392,8 +383,7 @@ do_format_bitstr(#c_bitstr{val=V,size=S,unit=U,type=T,flags=Fs}, Ctxt0) ->
["#<", Val, ">(", format_hseq(Vs,",", Ctxt2, fun format/2), $)].
format_clauses(Cs, Ctxt) ->
- format_vseq(Cs, "", "", set_class(Ctxt, clause),
- fun format_clause/2).
+ format_vseq(Cs, "", "", Ctxt, fun format_clause/2).
format_clause(Node, Ctxt) ->
maybe_anno(Node, fun format_clause_1/2, Ctxt).
@@ -405,15 +395,13 @@ format_clause_1(#c_clause{pats=Ps,guard=G,body=B}, Ctxt) ->
case is_trivial_guard(G) of
true ->
[" when ",
- format_guard(G, add_indent(set_class(Ctxt, expr),
- width(Ptxt, Ctxt) + 6))];
+ format_guard(G, add_indent(Ctxt, width(Ptxt, Ctxt) + 6))];
false ->
[nl_indent(Ctxt2), "when ",
- format_guard(G, add_indent(set_class(Ctxt2, expr), 2))]
+ format_guard(G, add_indent(Ctxt2, 2))]
end++
" ->",
- nl_indent(Ctxt2)
- | format(B, set_class(Ctxt2, expr))
+ nl_indent(Ctxt2) | format(B, Ctxt2)
].
is_trivial_guard(#c_literal{val=Val}) when is_atom(Val) -> true;
@@ -467,7 +455,7 @@ format_list_tail(Tail, Ctxt) ->
format_map_pair(Op, K, V, Ctxt0) ->
Ctxt1 = add_indent(Ctxt0, 1),
- Txt = format(K, set_class(Ctxt1, expr)),
+ Txt = format(K, Ctxt1),
Ctxt2 = add_indent(Ctxt0, width(Txt, Ctxt1)),
[Txt,Op,format(V, Ctxt2)].
@@ -490,6 +478,7 @@ spaces(5) -> " ";
spaces(6) -> " ";
spaces(7) -> " ".
+%% Undo indentation done by nl_indent/1.
unindent(T, Ctxt) ->
unindent(T, Ctxt#ctxt.indent, []).
@@ -505,18 +494,11 @@ unindent([$\t|T], N, C) ->
unindent([spaces(Tab - N)|T], 0, C)
end;
unindent([L|T], N, C) when is_list(L) ->
- unindent(L, N, [T|C]);
-unindent([H|T], _, C) ->
- [H|[T|C]];
-unindent([], N, [H|T]) ->
- unindent(H, N, T);
-unindent([], _, []) -> [].
+ unindent(L, N, [T|C]).
width(Txt, Ctxt) ->
- try width(Txt, 0, Ctxt, [])
- catch error:_ -> exit({bad_text,Txt})
- end.
+ width(Txt, 0, Ctxt, []).
width([$\t|T], A, Ctxt, C) ->
width(T, A + ?TAB_WIDTH, Ctxt, C);
@@ -533,14 +515,9 @@ width([], A, _, []) -> A.
add_indent(Ctxt, Dx) ->
Ctxt#ctxt{indent = Ctxt#ctxt.indent + Dx}.
-set_class(Ctxt, Class) ->
- Ctxt#ctxt{class = Class}.
-
core_atom(A) -> io_lib:write_string(atom_to_list(A), $').
-is_simple_term(#c_values{es=Es}) ->
- length(Es) < 3 andalso lists:all(fun is_simple_term/1, Es);
is_simple_term(#c_tuple{es=Es}) ->
length(Es) < 4 andalso lists:all(fun is_simple_term/1, Es);
is_simple_term(#c_var{}) -> true;
diff --git a/lib/compiler/test/Makefile b/lib/compiler/test/Makefile
index 85118502e3..203a50db55 100644
--- a/lib/compiler/test/Makefile
+++ b/lib/compiler/test/Makefile
@@ -9,6 +9,7 @@ MODULES= \
andor_SUITE \
apply_SUITE \
beam_block_SUITE \
+ beam_bool_SUITE \
beam_validator_SUITE \
beam_disasm_SUITE \
beam_except_SUITE \
@@ -46,6 +47,7 @@ NO_OPT= \
andor \
apply \
beam_block \
+ beam_bool \
beam_except \
beam_reorder \
beam_type \
@@ -70,6 +72,7 @@ INLINE= \
andor \
apply \
beam_block \
+ beam_bool \
beam_utils \
bs_bincomp \
bs_bit_binaries \
diff --git a/lib/compiler/test/andor_SUITE.erl b/lib/compiler/test/andor_SUITE.erl
index f6e7b09010..05c087104d 100644
--- a/lib/compiler/test/andor_SUITE.erl
+++ b/lib/compiler/test/andor_SUITE.erl
@@ -22,8 +22,7 @@
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2,
t_case/1,t_and_or/1,t_andalso/1,t_orelse/1,inside/1,overlap/1,
- combined/1,in_case/1,before_and_inside_if/1,
- slow_compilation/1]).
+ combined/1,in_case/1,slow_compilation/1]).
-include_lib("common_test/include/ct.hrl").
@@ -36,7 +35,7 @@ all() ->
groups() ->
[{p,[parallel],
[t_case,t_and_or,t_andalso,t_orelse,inside,overlap,
- combined,in_case,before_and_inside_if]}].
+ combined,in_case,slow_compilation]}].
init_per_suite(Config) ->
Config.
@@ -450,64 +449,6 @@ in_case_1_guard(LenUp, LenDw, LenN, Rotation, Count) ->
false -> loop
end.
-before_and_inside_if(Config) when is_list(Config) ->
- no = before_and_inside_if([a], [b], delete),
- no = before_and_inside_if([a], [b], x),
- no = before_and_inside_if([a], [], delete),
- no = before_and_inside_if([a], [], x),
- no = before_and_inside_if([], [], delete),
- yes = before_and_inside_if([], [], x),
- yes = before_and_inside_if([], [b], delete),
- yes = before_and_inside_if([], [b], x),
-
- {ch1,ch2} = before_and_inside_if_2([a], [b], blah),
- {ch1,ch2} = before_and_inside_if_2([a], [b], xx),
- {ch1,ch2} = before_and_inside_if_2([a], [], blah),
- {ch1,ch2} = before_and_inside_if_2([a], [], xx),
- {no,no} = before_and_inside_if_2([], [b], blah),
- {no,no} = before_and_inside_if_2([], [b], xx),
- {ch1,no} = before_and_inside_if_2([], [], blah),
- {no,ch2} = before_and_inside_if_2([], [], xx),
- ok.
-
-%% Thanks to Simon Cornish and Kostis Sagonas.
-%% Used to crash beam_bool.
-before_and_inside_if(XDo1, XDo2, Do3) ->
- Do1 = (XDo1 =/= []),
- Do2 = (XDo2 =/= []),
- if
- %% This expression occurs in a try/catch (protected)
- %% block, which cannot refer to variables outside of
- %% the block that are boolean expressions.
- Do1 =:= true;
- Do1 =:= false, Do2 =:= false, Do3 =:= delete ->
- no;
- true ->
- yes
- end.
-
-%% Thanks to Simon Cornish.
-%% Used to generate code that would not set {y,0} on
-%% all paths before its use (and therefore fail
-%% validation by the beam_validator).
-before_and_inside_if_2(XDo1, XDo2, Do3) ->
- Do1 = (XDo1 =/= []),
- Do2 = (XDo2 =/= []),
- CH1 = if Do1 == true;
- Do1 == false,Do2==false,Do3 == blah ->
- ch1;
- true ->
- no
- end,
- CH2 = if Do1 == true;
- Do1 == false,Do2==false,Do3 == xx ->
- ch2;
- true ->
- no
- end,
- {CH1,CH2}.
-
-
-record(state, {stack = []}).
slow_compilation(_) ->
diff --git a/lib/compiler/test/beam_block_SUITE.erl b/lib/compiler/test/beam_block_SUITE.erl
index 81f8d10687..d343e26737 100644
--- a/lib/compiler/test/beam_block_SUITE.erl
+++ b/lib/compiler/test/beam_block_SUITE.erl
@@ -35,7 +35,8 @@ all() ->
groups() ->
[{p,[parallel],
- [get_map_elements
+ [get_map_elements,
+ otp_7345
]}].
init_per_suite(Config) ->
diff --git a/lib/compiler/test/beam_bool_SUITE.erl b/lib/compiler/test/beam_bool_SUITE.erl
new file mode 100644
index 0000000000..84d634e5ca
--- /dev/null
+++ b/lib/compiler/test/beam_bool_SUITE.erl
@@ -0,0 +1,160 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2015-2016. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(beam_bool_SUITE).
+
+-export([all/0,suite/0,groups/0,init_per_suite/1,end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ before_and_inside_if/1,
+ scotland/1,y_registers/1]).
+
+suite() ->
+ [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ test_lib:recompile(?MODULE),
+ [{group,p}].
+
+groups() ->
+ [{p,[parallel],
+ [before_and_inside_if,
+ scotland,
+ y_registers
+ ]}].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+before_and_inside_if(_Config) ->
+ no = before_and_inside_if([a], [b], delete),
+ no = before_and_inside_if([a], [b], x),
+ no = before_and_inside_if([a], [], delete),
+ no = before_and_inside_if([a], [], x),
+ no = before_and_inside_if([], [], delete),
+ yes = before_and_inside_if([], [], x),
+ yes = before_and_inside_if([], [b], delete),
+ yes = before_and_inside_if([], [b], x),
+
+ {ch1,ch2} = before_and_inside_if_2([a], [b], blah),
+ {ch1,ch2} = before_and_inside_if_2([a], [b], xx),
+ {ch1,ch2} = before_and_inside_if_2([a], [], blah),
+ {ch1,ch2} = before_and_inside_if_2([a], [], xx),
+ {no,no} = before_and_inside_if_2([], [b], blah),
+ {no,no} = before_and_inside_if_2([], [b], xx),
+ {ch1,no} = before_and_inside_if_2([], [], blah),
+ {no,ch2} = before_and_inside_if_2([], [], xx),
+ ok.
+
+%% Thanks to Simon Cornish and Kostis Sagonas.
+%% Used to crash beam_bool.
+before_and_inside_if(XDo1, XDo2, Do3) ->
+ Do1 = (XDo1 =/= []),
+ Do2 = (XDo2 =/= []),
+ if
+ %% This expression occurs in a try/catch (protected)
+ %% block, which cannot refer to variables outside of
+ %% the block that are boolean expressions.
+ Do1 =:= true;
+ Do1 =:= false, Do2 =:= false, Do3 =:= delete ->
+ no;
+ true ->
+ yes
+ end.
+
+%% Thanks to Simon Cornish.
+%% Used to generate code that would not set {y,0} on
+%% all paths before its use (and therefore fail
+%% validation by the beam_validator).
+before_and_inside_if_2(XDo1, XDo2, Do3) ->
+ Do1 = (XDo1 =/= []),
+ Do2 = (XDo2 =/= []),
+ CH1 = if Do1 == true;
+ Do1 == false,Do2==false,Do3 == blah ->
+ ch1;
+ true ->
+ no
+ end,
+ CH2 = if Do1 == true;
+ Do1 == false,Do2==false,Do3 == xx ->
+ ch2;
+ true ->
+ no
+ end,
+ {CH1,CH2}.
+
+
+%% beam_bool would remove the initialization of {y,0}.
+%% (Thanks to Thomas Arts and QuickCheck.)
+
+scotland(_Config) ->
+ million = do_scotland(placed),
+ {'EXIT',{{badmatch,placed},_}} = (catch do_scotland(false)),
+ {'EXIT',{{badmatch,placed},_}} = (catch do_scotland(true)),
+ {'EXIT',{{badmatch,placed},_}} = (catch do_scotland(echo)),
+ ok.
+
+do_scotland(Echo) ->
+ found(case Echo of
+ Echo when true; Echo, Echo, Echo ->
+ Echo;
+ echo ->
+ []
+ end,
+ Echo = placed).
+
+found(_, _) -> million.
+
+
+%% ERL-143: beam_bool could not handle Y registers as a destination.
+y_registers(_Config) ->
+ {'EXIT',{badarith,[_|_]}} = (catch baker(valentine)),
+ {'EXIT',{badarith,[_|_]}} = (catch baker(clementine)),
+
+ {not_ok,true} = potter([]),
+ {ok,false} = potter([{encoding,any}]),
+
+ ok.
+
+%% Thanks to Quickcheck.
+baker(Baker) ->
+ (valentine == Baker) +
+ case Baker of
+ Baker when Baker; Baker ->
+ Baker;
+ Baker ->
+ []
+ end.
+
+%% Thanks to Jose Valim.
+potter(Modes) ->
+ Raw = lists:keyfind(encoding, 1, Modes) == false,
+ Final = case Raw of
+ X when X == false; X == nil -> ok;
+ _ -> not_ok
+ end,
+ {Final,Raw}.
diff --git a/lib/compiler/test/compile_SUITE.erl b/lib/compiler/test/compile_SUITE.erl
index e634f0fcc2..a15efc2a00 100644
--- a/lib/compiler/test/compile_SUITE.erl
+++ b/lib/compiler/test/compile_SUITE.erl
@@ -693,8 +693,7 @@ core(Config) when is_list(Config) ->
Outdir = filename:join(PrivDir, "core"),
ok = file:make_dir(Outdir),
- Wc = filename:join(filename:dirname(code:which(?MODULE)), "*.beam"),
- TestBeams = filelib:wildcard(Wc),
+ TestBeams = get_unique_beam_files(),
Abstr = [begin {ok,{Mod,[{abstract_code,
{raw_abstract_v1,Abstr}}]}} =
beam_lib:chunks(Beam, [abstract_code]),
@@ -755,8 +754,7 @@ core_roundtrip(Config) ->
Outdir = filename:join(PrivDir, atom_to_list(?FUNCTION_NAME)),
ok = file:make_dir(Outdir),
- Wc = filename:join(filename:dirname(code:which(?MODULE)), "*.beam"),
- TestBeams = filelib:wildcard(Wc),
+ TestBeams = get_unique_beam_files(),
test_lib:p_run(fun(F) -> do_core_roundtrip(F, Outdir) end, TestBeams).
do_core_roundtrip(Beam, Outdir) ->
@@ -781,8 +779,13 @@ do_core_roundtrip_1(Mod, Abstr, Outdir) ->
%% Primarily, test that annotations are accepted for all
%% constructs. Secondarily, smoke test cerl_trees:label/1.
- {Core,_} = cerl_trees:label(Core0),
- do_core_roundtrip_2(Mod, Core, Outdir).
+ {Core1,_} = cerl_trees:label(Core0),
+ do_core_roundtrip_2(Mod, Core1, Outdir),
+
+ %% Run the inliner to force generation of variables
+ %% with numeric names.
+ {ok,Mod,Core2} = compile:forms(Abstr, [inline,to_core]),
+ do_core_roundtrip_2(Mod, Core2, Outdir).
do_core_roundtrip_2(M, Core0, Outdir) ->
CoreFile = filename:join(Outdir, atom_to_list(M)++".core"),
@@ -870,8 +873,7 @@ asm(Config) when is_list(Config) ->
Outdir = filename:join(PrivDir, "asm"),
ok = file:make_dir(Outdir),
- Wc = filename:join(filename:dirname(code:which(?MODULE)), "*.beam"),
- TestBeams = filelib:wildcard(Wc),
+ TestBeams = get_unique_beam_files(),
Res = test_lib:p_run(fun(F) -> do_asm(F, Outdir) end, TestBeams),
Res.
@@ -947,8 +949,7 @@ dialyzer(Config) ->
%% Test that warnings contain filenames and line numbers.
warnings(_Config) ->
- TestDir = filename:dirname(code:which(?MODULE)),
- Files = filelib:wildcard(filename:join(TestDir, "*.erl")),
+ Files = get_unique_files(".erl"),
test_lib:p_run(fun do_warnings/1, Files).
do_warnings(F) ->
@@ -1102,3 +1103,14 @@ compile_and_verify(Name, Target, Opts) ->
beam_lib:chunks(Target, [compile_info]),
{options,BeamOpts} = lists:keyfind(options, 1, CInfo),
Opts = BeamOpts.
+
+get_unique_beam_files() ->
+ get_unique_files(".beam").
+
+get_unique_files(Ext) ->
+ Wc = filename:join(filename:dirname(code:which(?MODULE)), "*"++Ext),
+ [F || F <- filelib:wildcard(Wc), not is_cloned(F, Ext)].
+
+is_cloned(File, Ext) ->
+ Mod = list_to_atom(filename:basename(File, Ext)),
+ test_lib:is_cloned_mod(Mod).
diff --git a/lib/compiler/test/guard_SUITE.erl b/lib/compiler/test/guard_SUITE.erl
index 13d274d98a..83298e546e 100644
--- a/lib/compiler/test/guard_SUITE.erl
+++ b/lib/compiler/test/guard_SUITE.erl
@@ -34,7 +34,7 @@
tricky/1,rel_ops/1,rel_op_combinations/1,literal_type_tests/1,
basic_andalso_orelse/1,traverse_dcd/1,
check_qlc_hrl/1,andalso_semi/1,t_tuple_size/1,binary_part/1,
- bad_constants/1,bad_guards/1,scotland/1,
+ bad_constants/1,bad_guards/1,
guard_in_catch/1]).
suite() -> [{ct_hooks,[ts_install_cth]}].
@@ -54,7 +54,7 @@ groups() ->
rel_ops,rel_op_combinations,
literal_type_tests,basic_andalso_orelse,traverse_dcd,
check_qlc_hrl,andalso_semi,t_tuple_size,binary_part,
- bad_constants,bad_guards,scotland,guard_in_catch]}].
+ bad_constants,bad_guards,guard_in_catch]}].
init_per_suite(Config) ->
Config.
@@ -1852,27 +1852,6 @@ bad_guards_2(M, [_]) when M#{a := 0, b => 0}, map_size(M) ->
bad_guards_3(M, [_]) when is_map(M) andalso M#{a := 0, b => 0}, length(M) ->
ok.
-%% beam_bool would remove the initialization of {y,0}.
-%% (Thanks to Thomas Arts and QuickCheck.)
-
-scotland(_Config) ->
- million = do_scotland(placed),
- {'EXIT',{{badmatch,placed},_}} = (catch do_scotland(false)),
- {'EXIT',{{badmatch,placed},_}} = (catch do_scotland(true)),
- {'EXIT',{{badmatch,placed},_}} = (catch do_scotland(echo)),
- ok.
-
-do_scotland(Echo) ->
- found(case Echo of
- Echo when true; Echo, Echo, Echo ->
- Echo;
- echo ->
- []
- end,
- Echo = placed).
-
-found(_, _) -> million.
-
%% Building maps in a guard in a 'catch' would crash v3_codegen.
guard_in_catch(_Config) ->
diff --git a/lib/compiler/test/test_lib.erl b/lib/compiler/test/test_lib.erl
index d141d86021..d5b79e2357 100644
--- a/lib/compiler/test/test_lib.erl
+++ b/lib/compiler/test/test_lib.erl
@@ -22,7 +22,7 @@
-include_lib("common_test/include/ct.hrl").
-compile({no_auto_import,[binary_part/2]}).
-export([id/1,recompile/1,parallel/0,uniq/0,opt_opts/1,get_data_dir/1,
- smoke_disasm/1,p_run/2,binary_part/2]).
+ is_cloned_mod/1,smoke_disasm/1,p_run/2,binary_part/2]).
id(I) -> I.
@@ -91,6 +91,17 @@ get_data_dir(Config) ->
Data = re:replace(Data1, "_post_opt_SUITE", "_SUITE", Opts),
re:replace(Data, "_inline_SUITE", "_SUITE", Opts).
+is_cloned_mod(Mod) ->
+ is_cloned_mod_1(atom_to_list(Mod)).
+
+%% Test whether Mod is a cloned module.
+
+is_cloned_mod_1("no_opt_SUITE") -> true;
+is_cloned_mod_1("post_opt_SUITE") -> true;
+is_cloned_mod_1("inline_SUITE") -> true;
+is_cloned_mod_1([_|T]) -> is_cloned_mod_1(T);
+is_cloned_mod_1([]) -> false.
+
%% p_run(fun(Data) -> ok|error, List) -> ok
%% Will fail the test case if there were any errors.
@@ -106,8 +117,9 @@ p_run(Test, List) ->
%% slightly faster than using 3. Using more than
%% 4 would not buy us much and could actually be
%% slower.
- max(S, 4)
+ min(S, 4)
end,
+ io:format("p_run: ~p parallel processes\n", [N]),
p_run_loop(Test, List, N, [], 0, 0).
p_run_loop(_, [], _, [], Errors, Ws) ->
diff --git a/lib/compiler/test/trycatch_SUITE.erl b/lib/compiler/test/trycatch_SUITE.erl
index f7ad78cb8d..a591d6cc93 100644
--- a/lib/compiler/test/trycatch_SUITE.erl
+++ b/lib/compiler/test/trycatch_SUITE.erl
@@ -1034,6 +1034,9 @@ grab_bag(_Config) ->
end
end,
+ %% Unnecessary catch.
+ 22 = (catch 22),
+
ok.
diff --git a/lib/dialyzer/src/dialyzer_contracts.erl b/lib/dialyzer/src/dialyzer_contracts.erl
index 116260778c..d1ffa07706 100644
--- a/lib/dialyzer/src/dialyzer_contracts.erl
+++ b/lib/dialyzer/src/dialyzer_contracts.erl
@@ -479,7 +479,8 @@ initialize_constraints([], _MFA, _RecDict, _ExpTypes, _AllRecords, Acc) ->
initialize_constraints([Constr|Rest], MFA, RecDict, ExpTypes, AllRecords, Acc) ->
case Constr of
{type, _, constraint, [{atom, _, is_subtype}, [Type1, Type2]]} ->
- T1 = final_form(Type1, ExpTypes, MFA, AllRecords, maps:new()),
+ VarTable = erl_types:var_table__new(),
+ T1 = final_form(Type1, ExpTypes, MFA, AllRecords, VarTable),
Entry = {T1, Type2},
initialize_constraints(Rest, MFA, RecDict, ExpTypes, AllRecords, [Entry|Acc]);
{type, _, constraint, [{atom,_,Name}, List]} ->
@@ -489,8 +490,9 @@ initialize_constraints([Constr|Rest], MFA, RecDict, ExpTypes, AllRecords, Acc) -
end.
constraints_fixpoint(Constrs, MFA, RecDict, ExpTypes, AllRecords) ->
+ VarTable = erl_types:var_table__new(),
VarDict =
- constraints_to_dict(Constrs, MFA, RecDict, ExpTypes, AllRecords, maps:new()),
+ constraints_to_dict(Constrs, MFA, RecDict, ExpTypes, AllRecords, VarTable),
constraints_fixpoint(VarDict, MFA, Constrs, RecDict, ExpTypes, AllRecords).
constraints_fixpoint(OldVarDict, MFA, Constrs, RecDict, ExpTypes, AllRecords) ->
@@ -498,11 +500,11 @@ constraints_fixpoint(OldVarDict, MFA, Constrs, RecDict, ExpTypes, AllRecords) ->
constraints_to_dict(Constrs, MFA, RecDict, ExpTypes, AllRecords, OldVarDict),
case NewVarDict of
OldVarDict ->
- DictFold =
+ Fun =
fun(Key, Value, Acc) ->
[{subtype, erl_types:t_var(Key), Value}|Acc]
end,
- FinalConstrs = maps:fold(DictFold, [], NewVarDict),
+ FinalConstrs = maps:fold(Fun, [], NewVarDict),
{FinalConstrs, NewVarDict};
_Other ->
constraints_fixpoint(NewVarDict, MFA, Constrs, RecDict, ExpTypes, AllRecords)
@@ -512,12 +514,12 @@ final_form(Form, ExpTypes, MFA, AllRecords, VarDict) ->
from_form_with_check(Form, ExpTypes, MFA, AllRecords, VarDict).
from_form_with_check(Form, ExpTypes, MFA, AllRecords) ->
- from_form_with_check(Form, ExpTypes, MFA, AllRecords, maps:new()).
+ VarTable = erl_types:var_table__new(),
+ from_form_with_check(Form, ExpTypes, MFA, AllRecords, VarTable).
from_form_with_check(Form, ExpTypes, MFA, AllRecords, VarDict) ->
Site = {spec, MFA},
- erl_types:t_check_record_fields(Form, ExpTypes, Site, AllRecords,
- VarDict),
+ erl_types:t_check_record_fields(Form, ExpTypes, Site, AllRecords, VarDict),
erl_types:t_from_form(Form, ExpTypes, Site, AllRecords, VarDict).
constraints_to_dict(Constrs, MFA, RecDict, ExpTypes, AllRecords, VarDict) ->
diff --git a/lib/eldap/src/eldap.erl b/lib/eldap/src/eldap.erl
index dc236f8a44..625309271b 100644
--- a/lib/eldap/src/eldap.erl
+++ b/lib/eldap/src/eldap.erl
@@ -564,7 +564,12 @@ loop(Cpid, Data) ->
?MODULE:loop(Cpid, NewData);
{_From, close} ->
- {no_reply,_NewData} = do_unbind(Data),
+ % Ignore tcp error if connection is already closed.
+ try do_unbind(Data) of
+ {no_reply,_NewData} -> ok
+ catch
+ throw:{gen_tcp_error, _TcpErr} -> ok
+ end,
unlink(Cpid),
exit(closed);
diff --git a/lib/eldap/test/eldap_basic_SUITE.erl b/lib/eldap/test/eldap_basic_SUITE.erl
index 9a23f74e22..536e891a1e 100644
--- a/lib/eldap/test/eldap_basic_SUITE.erl
+++ b/lib/eldap/test/eldap_basic_SUITE.erl
@@ -94,7 +94,8 @@ connection_tests() ->
client_side_start_tls_timeout,
client_side_bind_timeout,
client_side_add_timeout,
- client_side_search_timeout
+ client_side_search_timeout,
+ close_after_tcp_error
].
@@ -312,6 +313,30 @@ tcp_connection(Config) ->
end.
%%%----------------------------------------------------------------
+
+close_after_tcp_error(Config) ->
+ Host = proplists:get_value(listen_host, Config),
+ Port = proplists:get_value(listen_port, Config),
+ Opts = proplists:get_value(tcp_connect_opts, Config),
+ T = 1000,
+ case eldap:open([Host], [{timeout,T},{port,Port}|Opts]) of
+ {ok,H} ->
+ Sl = proplists:get_value(listen_socket, Config),
+ gen_tcp:close(Sl),
+ {error,{gen_tcp_error,closed}} = eldap:simple_bind(H, anon, anon),
+ ok = eldap:close(H),
+ wait_for_close(H);
+ Other -> ct:fail("eldap:open failed: ~p",[Other])
+ end.
+
+wait_for_close(H) ->
+ case erlang:is_process_alive(H) of
+ true -> timer:sleep(100),
+ wait_for_close(H);
+ false -> ok
+ end.
+
+%%%----------------------------------------------------------------
ssl_connection(Config) ->
Host = proplists:get_value(listen_host, Config),
Port = proplists:get_value(ssl_listen_port, Config),
diff --git a/lib/erl_docgen/priv/xsl/db_html.xsl b/lib/erl_docgen/priv/xsl/db_html.xsl
index a3c71fea15..c2d7d40446 100644
--- a/lib/erl_docgen/priv/xsl/db_html.xsl
+++ b/lib/erl_docgen/priv/xsl/db_html.xsl
@@ -383,9 +383,7 @@
</xsl:choose>
</xsl:when>
<xsl:otherwise> <!-- <datatype> with <name> -->
- <span class="bold_code">
- <xsl:apply-templates/>
- </span>
+ <xsl:call-template name="name"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
@@ -1855,6 +1853,7 @@
</xsl:choose>
</xsl:template>
+ <!-- Used both in <datatype> and in <func>! -->
<xsl:template name="name">
<xsl:variable name="tmpstring">
@@ -1911,7 +1910,14 @@
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
- <a name="{$fname}-{$arity}"><span class="bold_code"><xsl:value-of select="."/></span></a><br/>
+ <xsl:choose>
+ <xsl:when test="ancestor::datatype">
+ <a name="type-{$fname}"><span class="bold_code"><xsl:value-of select="."/></span></a><br/>
+ </xsl:when>
+ <xsl:otherwise>
+ <a name="{$fname}-{$arity}"><span class="bold_code"><xsl:value-of select="."/></span></a><br/>
+ </xsl:otherwise>
+ </xsl:choose>
</xsl:when>
<xsl:otherwise>
<span class="bold_code"><xsl:value-of select="."/></span>
diff --git a/lib/erl_interface/test/ei_connect_SUITE_data/Makefile.src b/lib/erl_interface/test/ei_connect_SUITE_data/Makefile.src
index 5b82f0bfcf..c2d8261dd8 100644
--- a/lib/erl_interface/test/ei_connect_SUITE_data/Makefile.src
+++ b/lib/erl_interface/test/ei_connect_SUITE_data/Makefile.src
@@ -23,9 +23,10 @@ include @erl_interface_mk_include@
CC0 = @CC@
CC = ..@DS@all_SUITE_data@DS@gccifier@exe@ -CC"$(CC0)"
LD = @LD@
+LIBERL = @erl_interface_lib@
LIBEI = @erl_interface_eilib@
LIBFLAGS = ../all_SUITE_data/ei_runner@obj@ \
- $(LIBEI) @LIBS@ @erl_interface_sock_libs@ \
+ $(LIBERL) $(LIBEI) @LIBS@ @erl_interface_sock_libs@ \
@erl_interface_threadlib@
CFLAGS = @EI_CFLAGS@ $(THR_DEFS) -I@erl_interface_include@ -I../all_SUITE_data
EI_CONNECT_OBJS = ei_connect_test@obj@ ei_connect_test_decl@obj@
diff --git a/lib/erl_interface/test/ei_connect_SUITE_data/einode.c b/lib/erl_interface/test/ei_connect_SUITE_data/einode.c
index e1d46ae59a..bb71575740 100644
--- a/lib/erl_interface/test/ei_connect_SUITE_data/einode.c
+++ b/lib/erl_interface/test/ei_connect_SUITE_data/einode.c
@@ -35,6 +35,7 @@
#endif
#include "ei.h"
+#include "erl_interface.h"
#ifdef VXWORKS
#define MAIN cnode
@@ -115,6 +116,8 @@ MAIN(int argc, char *argv[])
if (argc < 3)
exit(1);
+ erl_init(NULL, 0);
+
cookie = argv[1];
n = atoi(argv[2]);
if (n > 100)
diff --git a/lib/hipe/cerl/erl_types.erl b/lib/hipe/cerl/erl_types.erl
index 84addcc105..b037a4360c 100644
--- a/lib/hipe/cerl/erl_types.erl
+++ b/lib/hipe/cerl/erl_types.erl
@@ -220,6 +220,7 @@
is_opaque_type/2,
is_erl_type/1,
atom_to_string/1,
+ var_table__new/0,
map_pairwise_merge/3
]).
@@ -236,7 +237,7 @@
-export([t_is_identifier/1]).
-endif.
--export_type([erl_type/0, opaques/0, type_table/0]).
+-export_type([erl_type/0, opaques/0, type_table/0, var_table/0]).
%%-define(DEBUG, true).
@@ -380,7 +381,7 @@
-type type_table() :: dict:dict(record_key() | type_key(),
record_value() | type_value()).
--type var_table() :: #{atom() => erl_type()}.
+-opaque var_table() :: #{atom() => erl_type()}.
%%-----------------------------------------------------------------------------
%% Unions
@@ -5464,6 +5465,17 @@ family(L) ->
sofs:to_external(F).
%%=============================================================================
+%%
+%% Interface functions for abstract data types defined in this module
+%%
+%%=============================================================================
+
+-spec var_table__new() -> var_table().
+
+var_table__new() ->
+ maps:new().
+
+%%=============================================================================
%% Consistency-testing function(s) below
%%=============================================================================
diff --git a/lib/inets/src/http_server/httpd_response.erl b/lib/inets/src/http_server/httpd_response.erl
index c0b5f09faf..1374b7e85e 100644
--- a/lib/inets/src/http_server/httpd_response.erl
+++ b/lib/inets/src/http_server/httpd_response.erl
@@ -390,8 +390,7 @@ send_response_old(#mod{socket_type = Type,
send_header(ModData, StatusCode, [{content_length,
content_length(NewResponse)}]),
httpd_socket:deliver(Type, Sock, NewResponse);
-
- {error, _Reason} ->
+ _ ->
send_status(ModData, 500, "Internal Server Error")
end.
diff --git a/lib/inets/src/http_server/mod_htaccess.erl b/lib/inets/src/http_server/mod_htaccess.erl
index 2bc0d79218..7b742bba24 100644
--- a/lib/inets/src/http_server/mod_htaccess.erl
+++ b/lib/inets/src/http_server/mod_htaccess.erl
@@ -412,8 +412,8 @@ getAuthenticatingDataFromHeader(Info)->
case httpd_util:split(UnCodedString,":",2) of
{ok,[User,PassWord]}->
{user,User,PassWord};
- {error,Error}->
- {error,Error}
+ Other ->
+ {error, Other}
end
end;
BadCredentials ->
diff --git a/lib/kernel/doc/src/application.xml b/lib/kernel/doc/src/application.xml
index 3928078932..8d33aa86e7 100644
--- a/lib/kernel/doc/src/application.xml
+++ b/lib/kernel/doc/src/application.xml
@@ -62,8 +62,7 @@
</datatype>
<datatype>
<name>tuple_of(T)</name>
- <desc><p><marker id="type-tuple_of"/>
- A tuple where the elements are of type <c>T</c>.</p></desc>
+ <desc><p>A tuple where the elements are of type <c>T</c>.</p></desc>
</datatype>
</datatypes>
<funcs>
diff --git a/lib/kernel/doc/src/file.xml b/lib/kernel/doc/src/file.xml
index a73038ac58..7d86c3ebcb 100644
--- a/lib/kernel/doc/src/file.xml
+++ b/lib/kernel/doc/src/file.xml
@@ -90,8 +90,7 @@
<datatype>
<name>fd()</name>
<desc>
- <p><marker id="type-fd"/>
- A file descriptor representing a file opened in
+ <p>A file descriptor representing a file opened in
<seealso marker="#raw"><c>raw</c></seealso> mode.</p>
</desc>
</datatype>
diff --git a/lib/kernel/doc/src/gen_sctp.xml b/lib/kernel/doc/src/gen_sctp.xml
index 57307cd594..737800c6b1 100644
--- a/lib/kernel/doc/src/gen_sctp.xml
+++ b/lib/kernel/doc/src/gen_sctp.xml
@@ -72,8 +72,7 @@
<datatype>
<name>assoc_id()</name>
<desc>
- <p><marker id="type-assoc_id"/>
- An opaque term returned in, for example, <c>#sctp_paddr_change{}</c>,
+ <p>An opaque term returned in, for example, <c>#sctp_paddr_change{}</c>,
which identifies an association for an SCTP socket. The term
is opaque except for the special value <c>0</c>, which has a
meaning such as "the whole endpoint" or "all future associations".</p>
@@ -88,12 +87,11 @@
</datatype>
<datatype>
<name name="option_name"/>
- <desc><marker id="type-sctp_socket"></marker></desc>
</datatype>
<datatype>
<name>sctp_socket()</name>
<desc>
- <p><marker id="type-sctp_socket"/>Socket identifier returned from
+ <p>Socket identifier returned from
<seealso marker="#open/0"><c>open/*</c></seealso>.</p>
<marker id="exports"></marker>
</desc>
diff --git a/lib/kernel/doc/src/gen_tcp.xml b/lib/kernel/doc/src/gen_tcp.xml
index 919178195f..8bd94892ad 100644
--- a/lib/kernel/doc/src/gen_tcp.xml
+++ b/lib/kernel/doc/src/gen_tcp.xml
@@ -79,8 +79,7 @@ do_recv(Sock, Bs) ->
</datatype>
<datatype>
<name>socket()</name>
- <desc><p><marker id="type-socket"/>
- As returned by
+ <desc><p>As returned by
<seealso marker="#accept/1"><c>accept/1,2</c></seealso> and
<seealso marker="#connect/3"><c>connect/3,4</c></seealso>.</p>
<marker id="connect"></marker>
diff --git a/lib/kernel/doc/src/gen_udp.xml b/lib/kernel/doc/src/gen_udp.xml
index 906883ed34..3db291600d 100644
--- a/lib/kernel/doc/src/gen_udp.xml
+++ b/lib/kernel/doc/src/gen_udp.xml
@@ -45,7 +45,6 @@
<datatype>
<name>socket()</name>
<desc>
- <marker id="type-socket"/>
<p>As returned by
<seealso marker="#open/1"><c>open/1,2</c></seealso>.</p>
</desc>
diff --git a/lib/kernel/doc/src/inet.xml b/lib/kernel/doc/src/inet.xml
index cfff393b8c..bca04aa244 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>2015</year>
+ <year>1997</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -128,7 +128,7 @@ fe80::204:acff:fe17:bf38
<datatype>
<name>socket()</name>
<desc>
- <p><marker id="type-socket"></marker>See
+ <p>See
<seealso marker="gen_tcp#type-socket"><c>gen_tcp:type-socket</c></seealso>
and
<seealso marker="gen_udp#type-socket"><c>gen_udp:type-socket</c></seealso>.
diff --git a/lib/kernel/test/erl_prim_loader_SUITE.erl b/lib/kernel/test/erl_prim_loader_SUITE.erl
index 4f3881d27e..b6417210b9 100644
--- a/lib/kernel/test/erl_prim_loader_SUITE.erl
+++ b/lib/kernel/test/erl_prim_loader_SUITE.erl
@@ -108,13 +108,18 @@ get_file(Config) when is_list(Config) ->
error = erl_prim_loader:get_file({dummy}),
ok.
-get_modules(_Config) ->
+get_modules(Config) ->
case test_server:is_cover() of
- false -> do_get_modules();
+ false -> do_get_modules(Config);
true -> {skip,"Cover"}
end.
-do_get_modules() ->
+do_get_modules(Config) ->
+ PrivDir = proplists:get_value(priv_dir, Config),
+ NotADir = atom_to_list(?FUNCTION_NAME) ++ "_not_a_dir",
+ ok = file:write_file(filename:join(PrivDir, NotADir), <<>>),
+ ok = file:set_cwd(PrivDir),
+
MsGood = lists:sort([lists,gen_server,gb_trees,code_server]),
Ms = [certainly_not_existing|MsGood],
SuccExp = [begin
@@ -129,8 +134,10 @@ do_get_modules() ->
Path = code:get_path(),
Process = fun(_, F, Code) -> {ok,{F,erlang:md5(Code)}} end,
- {ok,{Succ,FailExp}} = erl_prim_loader:get_modules(Ms, Process, Path),
- SuccExp = lists:sort(Succ),
+ {ok,{SuccExp,FailExp}} = get_modules_sorted(Ms, Process, Path),
+
+ %% Test that an 'enotdir' error can be handled.
+ {ok,{SuccExp,FailExp}} = get_modules_sorted(Ms, Process, [NotADir|Path]),
Name = inet_get_modules,
{ok, Node, BootPid} = complete_start_node(Name),
@@ -147,6 +154,13 @@ do_get_modules() ->
ok.
+get_modules_sorted(Ms, Process, Path) ->
+ case erl_prim_loader:get_modules(Ms, Process, Path) of
+ {ok,{Succ,FailExp}} ->
+ {ok,{lists:sort(Succ),lists:sort(FailExp)}};
+ Other ->
+ Other
+ end.
normalize_and_backslash(Config) ->
%% Test OTP-11170
diff --git a/lib/os_mon/c_src/cpu_sup.c b/lib/os_mon/c_src/cpu_sup.c
index 61bf1b0352..353c7e674e 100644
--- a/lib/os_mon/c_src/cpu_sup.c
+++ b/lib/os_mon/c_src/cpu_sup.c
@@ -47,6 +47,10 @@
#include <kstat.h>
#endif
+#if (defined(__APPLE__) && defined(__MACH__))
+#include <mach/mach.h>
+#endif
+
#include <errno.h>
#if defined(__sun__) || defined(__linux__)
@@ -73,6 +77,10 @@ typedef struct {
#endif
+#if (defined(__APPLE__) && defined(__MACH__))
+#define CU_OSX_VALUES (5)
+#endif
+
#if defined(__FreeBSD__)
#include <sys/resource.h>
#include <sys/sysctl.h>
@@ -164,7 +172,7 @@ static int processors_online() {
}
#endif
-#if defined(__FreeBSD__)
+#if (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD__)
void getsysctl(const char *, void *, size_t);
#endif
@@ -173,7 +181,7 @@ int main(int argc, char** argv) {
int rc;
int sz;
unsigned int *rv;
-#if defined(__linux__) || defined(__FreeBSD__)
+#if defined(__linux__) || (defined(__APPLE__) && defined(__MACH__)) ||defined(__FreeBSD__)
unsigned int no_of_cpus = 0;
#endif
@@ -190,6 +198,13 @@ int main(int argc, char** argv) {
}
#endif
+#if (defined(__APPLE__) && defined(__MACH__))
+ getsysctl("hw.ncpu", &no_of_cpus, sizeof(int));
+ if ( (rv = (unsigned int*)malloc(sizeof(unsigned int)*(2 + 2*no_of_cpus*CU_OSX_VALUES))) == NULL) {
+ error("cpu_sup: malloc error");
+ }
+#endif
+
#if defined(__FreeBSD__)
getsysctl("hw.ncpu", &no_of_cpus, sizeof(int));
if ( (rv = (unsigned int*)malloc(sizeof(unsigned int)*(2 + 2*no_of_cpus*CU_BSD_VALUES))) == NULL) {
@@ -222,7 +237,7 @@ int main(int argc, char** argv) {
case AVG5: bsd_loadavg(1); break;
case AVG15: bsd_loadavg(2); break;
#endif
-#if defined(__sun__) || defined(__linux__) || defined(__FreeBSD__)
+#if defined(__sun__) || defined(__linux__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD__)
case UTIL: util_measure(&rv,&sz); sendv(rv, sz); break;
#endif
case QUIT: free((void*)rv); return 0;
@@ -538,20 +553,60 @@ static void util_measure(unsigned int **result_vec, int *result_sz) {
#endif
/* ---------------------------- *
- * FreeBSD stat functions *
+ * OSX util functions *
* ---------------------------- */
-#if defined(__FreeBSD__)
+#if (defined(__APPLE__) && defined(__MACH__))
-#define EXIT_WITH(msg) (rich_error(msg, __FILE__, __LINE__))
-#define RICH_BUFLEN (213) /* left in error(char*) */
+static void util_measure(unsigned int **result_vec, int *result_sz) {
+ natural_t no_of_cpus;
+ processor_info_array_t info_array;
+ mach_msg_type_number_t info_count;
+ mach_port_t host_port;
+ kern_return_t error;
+ processor_cpu_load_info_data_t *cpu_load_info = NULL;
+ unsigned int *rv = NULL;
+ int i;
-void rich_error(const char *reason, const char *file, const int line) {
- char buf[RICH_BUFLEN];
- snprintf(buf, RICH_BUFLEN, "%s (%s:%i)", reason, file, line);
- error(buf);
+ host_port = mach_host_self();
+ error = host_processor_info(host_port, PROCESSOR_CPU_LOAD_INFO,
+ &no_of_cpus, &info_array, &info_count);
+ if (error != KERN_SUCCESS) {
+ *result_sz = 0;
+ return;
+ }
+ mach_port_deallocate(mach_task_self(), host_port);
+ cpu_load_info = (processor_cpu_load_info_data_t *) info_array;
+
+ rv = *result_vec;
+ rv[0] = no_of_cpus;
+ rv[1] = CU_OSX_VALUES;
+ ++rv; /* first value is number of cpus */
+ ++rv; /* second value is number of entries */
+
+ for (i = 0; i < no_of_cpus; ++i) {
+ rv[0] = CU_CPU_ID; rv[1] = i;
+ rv[2] = CU_USER; rv[3] = cpu_load_info[i].cpu_ticks[CPU_STATE_USER];
+ rv[4] = CU_NICE_USER; rv[5] = cpu_load_info[i].cpu_ticks[CPU_STATE_NICE];
+ rv[6] = CU_KERNEL; rv[7] = cpu_load_info[i].cpu_ticks[CPU_STATE_SYSTEM];
+ rv[8] = CU_IDLE; rv[9] = cpu_load_info[i].cpu_ticks[CPU_STATE_IDLE];
+ rv += CU_OSX_VALUES*2;
+ }
+
+ *result_sz = 2 + 2*CU_OSX_VALUES * no_of_cpus;
+
+ error = vm_deallocate(mach_task_self(), (vm_address_t)info_array,
+ info_count * sizeof(int));
+ if (error != KERN_SUCCESS)
+ *result_sz = 0;
}
-#undef RICH_BUFLEN
+#endif
+
+/* ---------------------------- *
+ * FreeBSD stat functions *
+ * ---------------------------- */
+
+#if defined(__FreeBSD__)
static void util_measure(unsigned int **result_vec, int *result_sz) {
int no_of_cpus;
@@ -588,6 +643,23 @@ static void util_measure(unsigned int **result_vec, int *result_sz) {
*result_sz = 2 + 2*CU_BSD_VALUES * no_of_cpus;
}
+#endif
+
+/* ---------------------------- *
+ * Utils for OSX and FreeBSD *
+ * ---------------------------- */
+
+#if (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD__)
+
+#define EXIT_WITH(msg) (rich_error(msg, __FILE__, __LINE__))
+#define RICH_BUFLEN (213) /* left in error(char*) */
+
+void rich_error(const char *reason, const char *file, const int line) {
+ char buf[RICH_BUFLEN];
+ snprintf(buf, RICH_BUFLEN, "%s (%s:%i)", reason, file, line);
+ error(buf);
+}
+#undef RICH_BUFLEN
void getsysctl(const char *name, void *ptr, size_t len)
{
diff --git a/lib/os_mon/src/cpu_sup.erl b/lib/os_mon/src/cpu_sup.erl
index 5eb067a5a3..e758b63d19 100644
--- a/lib/os_mon/src/cpu_sup.erl
+++ b/lib/os_mon/src/cpu_sup.erl
@@ -162,7 +162,8 @@ handle_call({?util, D, PC}, {Client, _Tag},
#state{os_type = {unix, Flavor}} = State)
when Flavor == sunos;
Flavor == linux;
- Flavor == freebsd ->
+ Flavor == freebsd;
+ Flavor == darwin ->
case measurement_server_call(State#state.server, {?util, D, PC, Client}) of
{error, Reason} ->
{ reply,
diff --git a/lib/os_mon/src/memsup.erl b/lib/os_mon/src/memsup.erl
index d9d3083540..4729d090f8 100644
--- a/lib/os_mon/src/memsup.erl
+++ b/lib/os_mon/src/memsup.erl
@@ -699,6 +699,8 @@ get_os_wordsize_with_uname() ->
case String of
"x86_64" -> 64;
"sparc64" -> 64;
+ "amd64" -> 64;
+ "ppc64" -> 64;
_ -> 32
end.
diff --git a/lib/os_mon/test/cpu_sup_SUITE.erl b/lib/os_mon/test/cpu_sup_SUITE.erl
index 11648d3547..41115ee6e2 100644
--- a/lib/os_mon/test/cpu_sup_SUITE.erl
+++ b/lib/os_mon/test/cpu_sup_SUITE.erl
@@ -63,6 +63,8 @@ all() ->
[load_api, util_api, util_values, port, unavailable];
{unix, freebsd} ->
[load_api, util_api, util_values, port, unavailable];
+ {unix, darwin} ->
+ [load_api, util_api, util_values, port, unavailable];
{unix, _OSname} -> [load_api];
_OS -> [unavailable]
end.
diff --git a/lib/os_mon/test/memsup_SUITE.erl b/lib/os_mon/test/memsup_SUITE.erl
index fcd1417693..e40ed574e7 100644
--- a/lib/os_mon/test/memsup_SUITE.erl
+++ b/lib/os_mon/test/memsup_SUITE.erl
@@ -100,10 +100,16 @@ api(Config) when is_list(Config) ->
%% get_os_wordsize()
ok = case memsup:get_os_wordsize() of
- 32 -> ok;
- 64 -> ok;
- unsupported_os -> ok;
- _ -> error
+ 32 ->
+ 32 = 8*erlang:system_info({wordsize,external}),
+ ok;
+ 64 ->
+ % No reliable test here
+ ok;
+ unsupported_os ->
+ ok;
+ _ ->
+ error
end,
%% get_check_interval()
diff --git a/lib/percept/src/egd_primitives.erl b/lib/percept/src/egd_primitives.erl
index 7b6e15efe7..b64189c552 100644
--- a/lib/percept/src/egd_primitives.erl
+++ b/lib/percept/src/egd_primitives.erl
@@ -23,32 +23,27 @@
-module(egd_primitives).
--export([
- create/2,
- color/1,
- pixel/3,
- polygon/3,
- line/4,
- line/5,
- arc/4,
- arc/5,
- rectangle/4,
- filledRectangle/4,
- filledEllipse/4,
- filledTriangle/5,
- text/5
- ]).
-
--export([
- info/1,
- object_info/1,
- rgb_float2byte/1
- ]).
--export([
- arc_to_edges/3,
- convex_hull/1,
- edges/1
- ]).
+-export([create/2,
+ color/1,
+ pixel/3,
+ polygon/3,
+ line/4,
+ line/5,
+ arc/4,
+ arc/5,
+ rectangle/4,
+ filledRectangle/4,
+ filledEllipse/4,
+ filledTriangle/5,
+ text/5]).
+
+-export([info/1,
+ object_info/1,
+ rgb_float2byte/1]).
+
+-export([arc_to_edges/3,
+ convex_hull/1,
+ edges/1]).
-include("egd.hrl").
@@ -75,22 +70,16 @@ object_info(O) ->
%% interface functions
-line(I, Sp, Ep, Color) ->
- I#image{ objects = [
- #image_object{
- type = line,
- points = [Sp, Ep],
- span = span([Sp, Ep]),
- color = Color} | I#image.objects]}.
+line(#image{objects=Os}=I, Sp, Ep, Color) ->
+ line(#image{objects=Os}=I, Sp, Ep, 1, Color).
-line(I, Sp, Ep, Stroke, Color) ->
- I#image{ objects = [
- #image_object{
- type = line,
- points = [Sp, Ep],
- span = span([Sp, Ep]),
- internals = Stroke,
- color = Color } | I#image.objects]}.
+line(#image{objects=Os}=I, Sp, Ep, Wd, Color) ->
+ I#image{objects=[#image_object{
+ internals = Wd,
+ type = line,
+ points = [Sp, Ep],
+ span = span([Sp, Ep]),
+ color = Color}|Os]}.
arc(I, {Sx,Sy} = Sp, {Ex,Ey} = Ep, Color) ->
X = Ex - Sx,
@@ -98,241 +87,234 @@ arc(I, {Sx,Sy} = Sp, {Ex,Ey} = Ep, Color) ->
R = math:sqrt(X*X + Y*Y)/2,
arc(I, Sp, Ep, R, Color).
-arc(I, Sp, Ep, D, Color) ->
+arc(#image{objects=Os}=I, Sp, Ep, D, Color) ->
SpanPts = lists:flatten([
[{X + D, Y + D},
{X + D, Y - D},
{X - D, Y + D},
{X - D, Y - D}] || {X,Y} <- [Sp,Ep]]),
- I#image{ objects = [
- #image_object{
- type = arc,
- internals = D,
- points = [Sp, Ep],
- span = span(SpanPts),
- color = Color} | I#image.objects]}.
+ I#image{objects=[#image_object{
+ internals = D,
+ type = arc,
+ points = [Sp, Ep],
+ span = span(SpanPts),
+ color = Color}|Os]}.
-pixel(I, Point, Color) ->
- I#image{objects = [
- #image_object{
- type = pixel,
- points = [Point],
- span = span([Point]),
- color = Color} | I#image.objects]}.
-
-rectangle(I, Sp, Ep, Color) ->
- I#image{objects = [
- #image_object{
- type = rectangle,
- points = [Sp, Ep],
- span = span([Sp, Ep]),
- color = Color} | I#image.objects]}.
-
-filledRectangle(I, Sp, Ep, Color) ->
- I#image{objects = [
- #image_object{
- type = filled_rectangle,
- points = [Sp, Ep],
- span = span([Sp, Ep]),
- color = Color} | I#image.objects]}.
-
-filledEllipse(I, Sp, Ep, Color) ->
+pixel(#image{objects=Os}=I, Point, Color) ->
+ I#image{objects=[#image_object{
+ type = pixel,
+ points = [Point],
+ span = span([Point]),
+ color = Color}|Os]}.
+
+rectangle(#image{objects=Os}=I, Sp, Ep, Color) ->
+ I#image{objects=[#image_object{
+ type = rectangle,
+ points = [Sp, Ep],
+ span = span([Sp, Ep]),
+ color = Color}|Os]}.
+
+filledRectangle(#image{objects=Os}=I, Sp, Ep, Color) ->
+ I#image{objects=[#image_object{
+ type = filled_rectangle,
+ points = [Sp, Ep],
+ span = span([Sp, Ep]),
+ color = Color}|Os]}.
+
+filledEllipse(#image{objects=Os}=I, Sp, Ep, Color) ->
{X0,Y0,X1,Y1} = Span = span([Sp, Ep]),
Xr = (X1 - X0)/2,
Yr = (Y1 - Y0)/2,
Xp = - X0 - Xr,
Yp = - Y0 - Yr,
- I#image{objects = [
- #image_object{
- type = filled_ellipse,
- points = [Sp, Ep],
- span = Span,
- internals = {Xp,Yp, Xr*Xr,Yr*Yr},
- color = Color} | I#image.objects]}.
-
-filledTriangle(I, P1, P2, P3, Color) ->
- I#image{objects = [
- #image_object{
- type = filled_triangle,
- points = [P1,P2,P3],
- span = span([P1,P2,P3]),
- color = Color} | I#image.objects]}.
-
-
-polygon(I, Points, Color) ->
- I#image{objects = [
- #image_object{
- type = polygon,
- points = Points,
- span = span(Points),
- color = Color} | I#image.objects]}.
+ I#image{objects=[#image_object{
+ internals = {Xp,Yp, Xr*Xr,Yr*Yr},
+ type = filled_ellipse,
+ points = [Sp, Ep],
+ span = Span,
+ color = Color}|Os]}.
+
+filledTriangle(#image{objects=Os}=I, P1, P2, P3, Color) ->
+ I#image{objects=[#image_object{
+ type = filled_triangle,
+ points = [P1,P2,P3],
+ span = span([P1,P2,P3]),
+ color = Color}|Os]}.
+
+polygon(#image{objects=Os}=I, Points, Color) ->
+ I#image{objects=[#image_object{
+ type = polygon,
+ points = Points,
+ span = span(Points),
+ color = Color}|Os]}.
+
+text(#image{objects=Os}=I, {Xs,Ys}=Sp, Font, Text, Color) ->
+ {FW,FH} = egd_font:size(Font),
+ Length = length(Text),
+ Ep = {Xs + Length*FW, Ys + FH + 5},
+ I#image{objects=[#image_object{
+ internals = {Font, Text},
+ type = text_horizontal,
+ points = [Sp],
+ span = span([Sp,Ep]),
+ color = Color}|Os]}.
create(W, H) ->
- #image{ width = W, height = H}.
+ #image{width = W, height = H}.
-
-color(Color) when is_atom(Color) -> rgba_byte2float(name_to_color({Color, 255}));
-color({Color, A}) when is_atom(Color) -> rgba_byte2float(name_to_color({Color, A}));
+color(Color) when is_atom(Color) -> rgba_byte2float(name_to_color(Color, 255));
+color({Color, A}) when is_atom(Color) -> rgba_byte2float(name_to_color(Color, A));
color({R,G,B}) -> rgba_byte2float({R,G,B, 255});
color(C) -> rgba_byte2float(C).
-% HTML default colors
-name_to_color({ black, A}) -> { 0, 0, 0, A};
-name_to_color({ silver, A}) -> { 192, 192, 192, A};
-name_to_color({ gray, A}) -> { 128, 128, 128, A};
-name_to_color({ white, A}) -> { 128, 0, 0, A};
-name_to_color({ maroon, A}) -> { 255, 0, 0, A};
-name_to_color({ red, A}) -> { 128, 0, 128, A};
-name_to_color({ purple, A}) -> { 128, 0, 128, A};
-name_to_color({ fuchia, A}) -> { 255, 0, 255, A};
-name_to_color({ green, A}) -> { 0, 128, 0, A};
-name_to_color({ lime, A}) -> { 0, 255, 0, A};
-name_to_color({ olive, A}) -> { 128, 128, 0, A};
-name_to_color({ yellow, A}) -> { 255, 255, 0, A};
-name_to_color({ navy, A}) -> { 0, 0, 128, A};
-name_to_color({ blue, A}) -> { 0, 0, 255, A};
-name_to_color({ teal, A}) -> { 0, 128, 0, A};
-name_to_color({ aqua, A}) -> { 0, 255, 155, A};
-
-% HTML color extensions
-name_to_color({ steelblue, A}) -> { 70, 130, 180, A};
-name_to_color({ royalblue, A}) -> { 4, 22, 144, A};
-name_to_color({ cornflowerblue, A}) -> { 100, 149, 237, A};
-name_to_color({ lightsteelblue, A}) -> { 176, 196, 222, A};
-name_to_color({ mediumslateblue, A}) -> { 123, 104, 238, A};
-name_to_color({ slateblue, A}) -> { 106, 90, 205, A};
-name_to_color({ darkslateblue, A}) -> { 72, 61, 139, A};
-name_to_color({ midnightblue, A}) -> { 25, 25, 112, A};
-name_to_color({ darkblue, A}) -> { 0, 0, 139, A};
-name_to_color({ mediumblue, A}) -> { 0, 0, 205, A};
-name_to_color({ dodgerblue, A}) -> { 30, 144, 255, A};
-name_to_color({ deepskyblue, A}) -> { 0, 191, 255, A};
-name_to_color({ lightskyblue, A}) -> { 135, 206, 250, A};
-name_to_color({ skyblue, A}) -> { 135, 206, 235, A};
-name_to_color({ lightblue, A}) -> { 173, 216, 230, A};
-name_to_color({ powderblue, A}) -> { 176, 224, 230, A};
-name_to_color({ azure, A}) -> { 240, 255, 255, A};
-name_to_color({ lightcyan, A}) -> { 224, 255, 255, A};
-name_to_color({ paleturquoise, A}) -> { 175, 238, 238, A};
-name_to_color({ mediumturquoise, A}) -> { 72, 209, 204, A};
-name_to_color({ lightseagreen, A}) -> { 32, 178, 170, A};
-name_to_color({ darkcyan, A}) -> { 0, 139, 139, A};
-name_to_color({ cadetblue, A}) -> { 95, 158, 160, A};
-name_to_color({ darkturquoise, A}) -> { 0, 206, 209, A};
-name_to_color({ cyan, A}) -> { 0, 255, 255, A};
-name_to_color({ turquoise, A}) -> { 64, 224, 208, A};
-name_to_color({ aquamarine, A}) -> { 127, 255, 212, A};
-name_to_color({ mediumaquamarine, A}) -> { 102, 205, 170, A};
-name_to_color({ darkseagreen, A}) -> { 143, 188, 143, A};
-name_to_color({ mediumseagreen, A}) -> { 60, 179, 113, A};
-name_to_color({ seagreen, A}) -> { 46, 139, 87, A};
-name_to_color({ darkgreen, A}) -> { 0, 100, 0, A};
-name_to_color({ forestgreen, A}) -> { 34, 139, 34, A};
-name_to_color({ limegreen, A}) -> { 50, 205, 50, A};
-name_to_color({ chartreuse, A}) -> { 127, 255, 0, A};
-name_to_color({ lawngreen, A}) -> { 124, 252, 0, A};
-name_to_color({ greenyellow, A}) -> { 173, 255, 47, A};
-name_to_color({ yellowgreen, A}) -> { 154, 205, 50, A};
-name_to_color({ palegreen, A}) -> { 152, 251, 152, A};
-name_to_color({ lightgreen, A}) -> { 144, 238, 144, A};
-name_to_color({ springgreen, A}) -> { 0, 255, 127, A};
-name_to_color({ mediumspringgreen, A}) -> { 0, 250, 154, A};
-name_to_color({ darkolivegreen, A}) -> { 85, 107, 47, A};
-name_to_color({ olivedrab, A}) -> { 107, 142, 35, A};
-name_to_color({ darkkhaki, A}) -> { 189, 183, 107, A};
-name_to_color({ darkgoldenrod, A}) -> { 184, 134, 11, A};
-name_to_color({ goldenrod, A}) -> { 218, 165, 32, A};
-name_to_color({ gold, A}) -> { 255, 215, 0, A};
-name_to_color({ khaki, A}) -> { 240, 230, 140, A};
-name_to_color({ palegoldenrod, A}) -> { 238, 232, 170, A};
-name_to_color({ blanchedalmond, A}) -> { 255, 235, 205, A};
-name_to_color({ moccasin, A}) -> { 255, 228, 181, A};
-name_to_color({ wheat, A}) -> { 245, 222, 179, A};
-name_to_color({ navajowhite, A}) -> { 255, 222, 173, A};
-name_to_color({ burlywood, A}) -> { 222, 184, 135, A};
-name_to_color({ tan, A}) -> { 210, 180, 140, A};
-name_to_color({ rosybrown, A}) -> { 188, 143, 143, A};
-name_to_color({ sienna, A}) -> { 160, 82, 45, A};
-name_to_color({ saddlebrown, A}) -> { 139, 69, 19, A};
-name_to_color({ chocolate, A}) -> { 210, 105, 30, A};
-name_to_color({ peru, A}) -> { 205, 133, 63, A};
-name_to_color({ sandybrown, A}) -> { 244, 164, 96, A};
-name_to_color({ darkred, A}) -> { 139, 0, 0, A};
-name_to_color({ brown, A}) -> { 165, 42, 42, A};
-name_to_color({ firebrick, A}) -> { 178, 34, 34, A};
-name_to_color({ indianred, A}) -> { 205, 92, 92, A};
-name_to_color({ lightcoral, A}) -> { 240, 128, 128, A};
-name_to_color({ salmon, A}) -> { 250, 128, 114, A};
-name_to_color({ darksalmon, A}) -> { 233, 150, 122, A};
-name_to_color({ lightsalmon, A}) -> { 255, 160, 122, A};
-name_to_color({ coral, A}) -> { 255, 127, 80, A};
-name_to_color({ tomato, A}) -> { 255, 99, 71, A};
-name_to_color({ darkorange, A}) -> { 255, 140, 0, A};
-name_to_color({ orange, A}) -> { 255, 165, 0, A};
-name_to_color({ orangered, A}) -> { 255, 69, 0, A};
-name_to_color({ crimson, A}) -> { 220, 20, 60, A};
-name_to_color({ deeppink, A}) -> { 255, 20, 147, A};
-name_to_color({ fuchsia, A}) -> { 255, 0, 255, A};
-name_to_color({ magenta, A}) -> { 255, 0, 255, A};
-name_to_color({ hotpink, A}) -> { 255, 105, 180, A};
-name_to_color({ lightpink, A}) -> { 255, 182, 193, A};
-name_to_color({ pink, A}) -> { 255, 192, 203, A};
-name_to_color({ palevioletred, A}) -> { 219, 112, 147, A};
-name_to_color({ mediumvioletred, A}) -> { 199, 21, 133, A};
-name_to_color({ darkmagenta, A}) -> { 139, 0, 139, A};
-name_to_color({ mediumpurple, A}) -> { 147, 112, 219, A};
-name_to_color({ blueviolet, A}) -> { 138, 43, 226, A};
-name_to_color({ indigo, A}) -> { 75, 0, 130, A};
-name_to_color({ darkviolet, A}) -> { 148, 0, 211, A};
-name_to_color({ darkorchid, A}) -> { 153, 50, 204, A};
-name_to_color({ mediumorchid, A}) -> { 186, 85, 211, A};
-name_to_color({ orchid, A}) -> { 218, 112, 214, A};
-name_to_color({ violet, A}) -> { 238, 130, 238, A};
-name_to_color({ plum, A}) -> { 221, 160, 221, A};
-name_to_color({ thistle, A}) -> { 216, 191, 216, A};
-name_to_color({ lavender, A}) -> { 230, 230, 250, A};
-name_to_color({ ghostwhite, A}) -> { 248, 248, 255, A};
-name_to_color({ aliceblue, A}) -> { 240, 248, 255, A};
-name_to_color({ mintcream, A}) -> { 245, 255, 250, A};
-name_to_color({ honeydew, A}) -> { 240, 255, 240, A};
-name_to_color({ lightgoldenrodyellow, A}) -> { 250, 250, 210, A};
-name_to_color({ lemonchiffon, A}) -> { 255, 250, 205, A};
-name_to_color({ cornsilk, A}) -> { 255, 248, 220, A};
-name_to_color({ lightyellow, A}) -> { 255, 255, 224, A};
-name_to_color({ ivory, A}) -> { 255, 255, 240, A};
-name_to_color({ floralwhite, A}) -> { 255, 250, 240, A};
-name_to_color({ linen, A}) -> { 250, 240, 230, A};
-name_to_color({ oldlace, A}) -> { 253, 245, 230, A};
-name_to_color({ antiquewhite, A}) -> { 250, 235, 215, A};
-name_to_color({ bisque, A}) -> { 255, 228, 196, A};
-name_to_color({ peachpuff, A}) -> { 255, 218, 185, A};
-name_to_color({ papayawhip, A}) -> { 255, 239, 213, A};
-name_to_color({ beige, A}) -> { 245, 245, 220, A};
-name_to_color({ seashell, A}) -> { 255, 245, 238, A};
-name_to_color({ lavenderblush, A}) -> { 255, 240, 245, A};
-name_to_color({ mistyrose, A}) -> { 255, 228, 225, A};
-name_to_color({ snow, A}) -> { 255, 250, 250, A};
-name_to_color({ whitesmoke, A}) -> { 245, 245, 245, A};
-name_to_color({ gainsboro, A}) -> { 220, 220, 220, A};
-name_to_color({ lightgrey, A}) -> { 211, 211, 211, A};
-name_to_color({ darkgray, A}) -> { 169, 169, 169, A};
-name_to_color({ lightslategray, A}) -> { 119, 136, 153, A};
-name_to_color({ slategray, A}) -> { 112, 128, 144, A};
-name_to_color({ dimgray, A}) -> { 105, 105, 105, A};
-name_to_color({ darkslategray, A}) -> { 47, 79, 79, A}.
-
-text(I, {Xs,Ys} = Sp, Font, Text, Color) ->
- {FW,FH} = egd_font:size(Font),
- Length = length(Text),
- Ep = {Xs + Length*FW, Ys + FH + 5},
- I#image{objects = [
- #image_object{
- type = text_horizontal,
- points = [Sp],
- span = span([Sp,Ep]),
- internals = {Font, Text},
- color = Color} | I#image.objects]}.
+name_to_color(Color, A) ->
+ case Color of
+ %% HTML default colors
+ black -> { 0, 0, 0, A};
+ silver -> {192, 192, 192, A};
+ gray -> {128, 128, 128, A};
+ white -> {128, 0, 0, A};
+ maroon -> {255, 0, 0, A};
+ red -> {128, 0, 128, A};
+ purple -> {128, 0, 128, A};
+ fuchia -> {255, 0, 255, A};
+ green -> { 0, 128, 0, A};
+ lime -> { 0, 255, 0, A};
+ olive -> {128, 128, 0, A};
+ yellow -> {255, 255, 0, A};
+ navy -> { 0, 0, 128, A};
+ blue -> { 0, 0, 255, A};
+ teal -> { 0, 128, 0, A};
+ aqua -> { 0, 255, 155, A};
+
+ %% HTML color extensions
+ steelblue -> { 70, 130, 180, A};
+ royalblue -> { 4, 22, 144, A};
+ cornflowerblue -> {100, 149, 237, A};
+ lightsteelblue -> {176, 196, 222, A};
+ mediumslateblue -> {123, 104, 238, A};
+ slateblue -> {106, 90, 205, A};
+ darkslateblue -> { 72, 61, 139, A};
+ midnightblue -> { 25, 25, 112, A};
+ darkblue -> { 0, 0, 139, A};
+ mediumblue -> { 0, 0, 205, A};
+ dodgerblue -> { 30, 144, 255, A};
+ deepskyblue -> { 0, 191, 255, A};
+ lightskyblue -> {135, 206, 250, A};
+ skyblue -> {135, 206, 235, A};
+ lightblue -> {173, 216, 230, A};
+ powderblue -> {176, 224, 230, A};
+ azure -> {240, 255, 255, A};
+ lightcyan -> {224, 255, 255, A};
+ paleturquoise -> {175, 238, 238, A};
+ mediumturquoise -> { 72, 209, 204, A};
+ lightseagreen -> { 32, 178, 170, A};
+ darkcyan -> { 0, 139, 139, A};
+ cadetblue -> { 95, 158, 160, A};
+ darkturquoise -> { 0, 206, 209, A};
+ cyan -> { 0, 255, 255, A};
+ turquoise -> { 64, 224, 208, A};
+ aquamarine -> {127, 255, 212, A};
+ mediumaquamarine -> {102, 205, 170, A};
+ darkseagreen -> {143, 188, 143, A};
+ mediumseagreen -> { 60, 179, 113, A};
+ seagreen -> { 46, 139, 87, A};
+ darkgreen -> { 0, 100, 0, A};
+ forestgreen -> { 34, 139, 34, A};
+ limegreen -> { 50, 205, 50, A};
+ chartreuse -> {127, 255, 0, A};
+ lawngreen -> {124, 252, 0, A};
+ greenyellow -> {173, 255, 47, A};
+ yellowgreen -> {154, 205, 50, A};
+ palegreen -> {152, 251, 152, A};
+ lightgreen -> {144, 238, 144, A};
+ springgreen -> { 0, 255, 127, A};
+ darkolivegreen -> { 85, 107, 47, A};
+ olivedrab -> {107, 142, 35, A};
+ darkkhaki -> {189, 183, 107, A};
+ darkgoldenrod -> {184, 134, 11, A};
+ goldenrod -> {218, 165, 32, A};
+ gold -> {255, 215, 0, A};
+ khaki -> {240, 230, 140, A};
+ palegoldenrod -> {238, 232, 170, A};
+ blanchedalmond -> {255, 235, 205, A};
+ moccasin -> {255, 228, 181, A};
+ wheat -> {245, 222, 179, A};
+ navajowhite -> {255, 222, 173, A};
+ burlywood -> {222, 184, 135, A};
+ tan -> {210, 180, 140, A};
+ rosybrown -> {188, 143, 143, A};
+ sienna -> {160, 82, 45, A};
+ saddlebrown -> {139, 69, 19, A};
+ chocolate -> {210, 105, 30, A};
+ peru -> {205, 133, 63, A};
+ sandybrown -> {244, 164, 96, A};
+ darkred -> {139, 0, 0, A};
+ brown -> {165, 42, 42, A};
+ firebrick -> {178, 34, 34, A};
+ indianred -> {205, 92, 92, A};
+ lightcoral -> {240, 128, 128, A};
+ salmon -> {250, 128, 114, A};
+ darksalmon -> {233, 150, 122, A};
+ lightsalmon -> {255, 160, 122, A};
+ coral -> {255, 127, 80, A};
+ tomato -> {255, 99, 71, A};
+ darkorange -> {255, 140, 0, A};
+ orange -> {255, 165, 0, A};
+ orangered -> {255, 69, 0, A};
+ crimson -> {220, 20, 60, A};
+ deeppink -> {255, 20, 147, A};
+ fuchsia -> {255, 0, 255, A};
+ magenta -> {255, 0, 255, A};
+ hotpink -> {255, 105, 180, A};
+ lightpink -> {255, 182, 193, A};
+ pink -> {255, 192, 203, A};
+ palevioletred -> {219, 112, 147, A};
+ mediumvioletred -> {199, 21, 133, A};
+ darkmagenta -> {139, 0, 139, A};
+ mediumpurple -> {147, 112, 219, A};
+ blueviolet -> {138, 43, 226, A};
+ indigo -> { 75, 0, 130, A};
+ darkviolet -> {148, 0, 211, A};
+ darkorchid -> {153, 50, 204, A};
+ mediumorchid -> {186, 85, 211, A};
+ orchid -> {218, 112, 214, A};
+ violet -> {238, 130, 238, A};
+ plum -> {221, 160, 221, A};
+ thistle -> {216, 191, 216, A};
+ lavender -> {230, 230, 250, A};
+ ghostwhite -> {248, 248, 255, A};
+ aliceblue -> {240, 248, 255, A};
+ mintcream -> {245, 255, 250, A};
+ honeydew -> {240, 255, 240, A};
+ lemonchiffon -> {255, 250, 205, A};
+ cornsilk -> {255, 248, 220, A};
+ lightyellow -> {255, 255, 224, A};
+ ivory -> {255, 255, 240, A};
+ floralwhite -> {255, 250, 240, A};
+ linen -> {250, 240, 230, A};
+ oldlace -> {253, 245, 230, A};
+ antiquewhite -> {250, 235, 215, A};
+ bisque -> {255, 228, 196, A};
+ peachpuff -> {255, 218, 185, A};
+ papayawhip -> {255, 239, 213, A};
+ beige -> {245, 245, 220, A};
+ seashell -> {255, 245, 238, A};
+ lavenderblush -> {255, 240, 245, A};
+ mistyrose -> {255, 228, 225, A};
+ snow -> {255, 250, 250, A};
+ whitesmoke -> {245, 245, 245, A};
+ gainsboro -> {220, 220, 220, A};
+ lightgrey -> {211, 211, 211, A};
+ darkgray -> {169, 169, 169, A};
+ lightslategray -> {119, 136, 153, A};
+ slategray -> {112, 128, 144, A};
+ dimgray -> {105, 105, 105, A};
+ darkslategray -> { 47, 79, 79, A};
+ mediumspringgreen -> { 0, 250, 154, A};
+ lightgoldenrodyellow -> {250, 250, 210, A}
+ end.
%%% Generic transformations
@@ -411,15 +393,17 @@ point_side(_) -> on_line.
%% AUX
-span(Points) ->
- Xs = [TX||{TX, _} <- Points],
- Ys = [TY||{_, TY} <- Points],
- Xmin = lists:min(Xs),
- Xmax = lists:max(Xs),
- Ymin = lists:min(Ys),
- Ymax = lists:max(Ys),
+span([{X0,Y0}|Points]) ->
+ span(Points,X0,Y0,X0,Y0).
+span([{X0,Y0}|Points],Xmin,Ymin,Xmax,Ymax) ->
+ span(Points,erlang:min(Xmin,X0),
+ erlang:min(Ymin,Y0),
+ erlang:max(Xmax,X0),
+ erlang:max(Ymax,Y0));
+span([],Xmin,Ymin,Xmax,Ymax) ->
{Xmin,Ymin,Xmax,Ymax}.
+
rgb_float2byte({R,G,B}) -> rgb_float2byte({R,G,B,1.0});
rgb_float2byte({R,G,B,A}) ->
{trunc(R*255), trunc(G*255), trunc(B*255), trunc(A*255)}.
diff --git a/lib/percept/src/egd_render.erl b/lib/percept/src/egd_render.erl
index 8ee41b66ab..c0075b8c42 100644
--- a/lib/percept/src/egd_render.erl
+++ b/lib/percept/src/egd_render.erl
@@ -27,6 +27,8 @@
-export([eps/1]).
-compile(inline).
+-export([line_to_linespans/3]).
+
-include("egd.hrl").
-define('DummyC',0).
@@ -216,11 +218,11 @@ parse_objects_on_line(Y, Width, Objects) ->
parse_objects_on_line(Y, 1, Width, Objects, []).
parse_objects_on_line(_Y, _Z, _, [], Out) -> lists:flatten(Out);
parse_objects_on_line(Y, Z, Width, [O|Os], Out) ->
- case is_object_on_line(Y, O) of
+ case is_object_on_line(O, Y) of
false ->
parse_objects_on_line(Y, Z + 1, Width, Os, Out);
true ->
- OLs = object_line_data(Y, Z, O),
+ OLs = object_line_data(O,Y,Z),
TOLs = trim_object_line_data(OLs, Width),
parse_objects_on_line(Y, Z + 1, Width, Os, [TOLs|Out])
end.
@@ -238,9 +240,9 @@ trim_object_line_data([{Z, Xl, Xr, C}|OLs], Width, Out) ->
% object_line_data
% In:
+% Object :: image_object()
% Y :: index of height
% Z :: index of depth
-% Object :: image_object()
% Out:
% OLs = [{Z, Xl, Xr, Color}]
% Z = index of height
@@ -250,96 +252,93 @@ trim_object_line_data([{Z, Xl, Xr, C}|OLs], Width, Out) ->
% Calculate the length (start and finish index) of an objects horizontal
% line given the height index.
-object_line_data(Y, Z, Object) ->
- object_line_data(Y, Z, Object, Object#image_object.type).
-object_line_data(Y, Z, #image_object{ span = {X0, Y0, X1, Y1}, color = C}, rectangle) ->
+object_line_data(#image_object{type=rectangle,
+ span={X0,Y0,X1,Y1}, color=C}, Y, Z) ->
if
- Y0 =:= Y ; Y1 =:= Y ->
- [{Z, X0, X1, C}];
- true ->
- [{Z, X0, X0, C},
- {Z, X1, X1, C}]
+ Y0 =:= Y ; Y1 =:= Y ->
+ [{Z, X0, X1, C}];
+ true ->
+ [{Z, X0, X0, C},
+ {Z, X1, X1, C}]
end;
-object_line_data(_Y, Z, #image_object{ span = {X0, _, X1, _}, color = C}, filled_rectangle) ->
+object_line_data(#image_object{type=filled_rectangle,
+ span={X0, _, X1, _}, color=C}, _Y, Z) ->
[{Z, X0, X1, C}];
-object_line_data(Y, Z, #image_object{ internals={Xr,Yr,Yr2}, span = {X0,Y0,X1,Y1}, color = C}, filled_ellipse) ->
+object_line_data(#image_object{type=filled_ellipse,
+ internals={Xr,Yr,Yr2}, span={X0,Y0,X1,Y1}, color=C}, Y, Z) ->
if
- X1 - X0 == 0; Y1 - Y0 == 0 ->
- [{Z, X0, X1, C}];
- true ->
- Yo = trunc(Y - Y0 - Yr),
- Yo2 = Yo*Yo,
- Xo = math:sqrt((1 - Yo2/Yr2))*Xr,
- [{Z, round(X0 - Xo + Xr), round(X0 + Xo + Xr), C}]
+ X1 - X0 =:= 0; Y1 - Y0 =:= 0 ->
+ [{Z, X0, X1, C}];
+ true ->
+ Yo = trunc(Y - Y0 - Yr),
+ Yo2 = Yo*Yo,
+ Xo = math:sqrt((1 - Yo2/Yr2))*Xr,
+ [{Z, round(X0 - Xo + Xr), round(X0 + Xo + Xr), C}]
end;
-object_line_data(Y, Z, #image_object{ intervals = Is, color = C}, filled_triangle) ->
+object_line_data(#image_object{type=filled_triangle,
+ intervals=Is, color=C}, Y, Z) ->
case lists:keyfind(Y, 1, Is) of
{Y, Xl, Xr} -> [{Z, Xl, Xr, C}];
false -> []
end;
-object_line_data(Y, Z, #image_object{ intervals = Is, color = C}, line) ->
- case dict:find(Y, Is) of
- {ok, Ls} -> [{Z, Xl, Xr, C}||{Xl,Xr} <- Ls];
+object_line_data(#image_object{type=line,
+ intervals=M, color={R,G,B,_}}, Y, Z) ->
+ case M of
+ #{Y := Ls} -> [{Z, Xl, Xr, {R,G,B,1.0-C/255}}||{Xl,Xr,C} <- Ls];
_ -> []
end;
-object_line_data(Y, Z, #image_object{ color = C, intervals = Is}, polygon) ->
+object_line_data(#image_object{type=polygon,
+ color=C, intervals=Is}, Y, Z) ->
[{Z, Xl, Xr, C} || {Yp, Xl, Xr} <- Is, Yp =:= Y];
-object_line_data(Y, Z, #image_object{ color = C, intervals = Is}, text_horizontal) ->
+object_line_data(#image_object{type=text_horizontal,
+ color=C, intervals=Is}, Y, Z) ->
[{Z, Xl, Xr, C} || {Yg, Xl, Xr} <- Is, Yg =:= Y];
-object_line_data(_, Z, #image_object{ span = {X0,_,X1,_}, color = C}, _) ->
+object_line_data(#image_object{type=pixel,
+ span={X0,_,X1,_}, color=C}, _, Z) ->
[{Z, X0, X1, C}].
-is_object_on_line(Y, #image_object{ span = Span }) ->
- is_object_bounds_on_line(Y, Span).
+is_object_on_line(#image_object{span={_,Y0,_,Y1}}, Y) ->
+ if Y < Y0; Y > Y1 -> false;
+ true -> true
+ end.
-is_object_bounds_on_line(Y, {_,Y0,_,Y1}) when Y < Y0 ; Y > Y1 -> false;
-is_object_bounds_on_line(_, _) -> true.
-
%%% primitives to line_spans
%% compile objects to linespans
-precompile(Image = #image{ objects = Os }) ->
- Image#image{ objects = precompile_objects(Os) }.
-
-precompile_objects(Os) -> precompile_objects(Os, []).
-precompile_objects([], Out) -> lists:reverse(Out);
-
-precompile_objects([O = #image_object{ type = line, points = [P0,P1] }| Os], Out) ->
- precompile_objects(Os, [O#image_object{ intervals = ls_list2dict(line_ls(P0,P1)) } | Out]);
-
-precompile_objects([O = #image_object{ type = filled_triangle, points = [P0,P1,P2] } | Os], Out) ->
- precompile_objects(Os, [O#image_object{ intervals = triangle_ls(P0,P1,P2) } | Out]);
-
-precompile_objects([O = #image_object{ type = polygon, points = Pts } | Os], Out) ->
- precompile_objects(Os, [O#image_object{ intervals = polygon_ls(Pts) } | Out]);
-
-precompile_objects([O = #image_object{ type = filled_ellipse, span = {X0,Y0,X1,Y1} } | Os], Out) ->
+precompile(#image{objects = Os}=I) ->
+ I#image{objects = precompile_objects(Os)}.
+
+precompile_objects([]) -> [];
+precompile_objects([#image_object{type=line, internals=W, points=[P0,P1]}=O|Os]) ->
+ [O#image_object{intervals = linespans_to_map(line_to_linespans(P0,P1,W))}|precompile_objects(Os)];
+precompile_objects([#image_object{type=filled_triangle, points=[P0,P1,P2]}=O|Os]) ->
+ [O#image_object{intervals = triangle_ls(P0,P1,P2)}|precompile_objects(Os)];
+precompile_objects([#image_object{type=polygon, points=Pts}=O|Os]) ->
+ [O#image_object{intervals = polygon_ls(Pts)}|precompile_objects(Os)];
+precompile_objects([#image_object{type=filled_ellipse, span={X0,Y0,X1,Y1}}=O|Os]) ->
Xr = (X1 - X0)/2,
Yr = (Y1 - Y0)/2,
Yr2 = Yr*Yr,
- precompile_objects(Os, [ O#image_object{ internals={Xr,Yr,Yr2} } | Out]);
-
-precompile_objects([O = #image_object{ type = arc, points = [P0,P1], internals = D }| Os], Out) ->
+ [O#image_object{internals={Xr,Yr,Yr2}}|precompile_objects(Os)];
+precompile_objects([#image_object{type=arc, points=[P0,P1], internals=D}=O|Os]) ->
Es = egd_primitives:arc_to_edges(P0, P1, D),
- Ls = lists:foldl(fun
- ({Ep0, Ep1}, D0) ->
- ls_list2dict(line_ls(Ep0, Ep1), D0)
- end, dict:new(), Es),
- precompile_objects(Os, [O#image_object{ type = line, intervals = Ls } | Out]);
-
-precompile_objects([O = #image_object{ type = text_horizontal, points = [P0], internals = {Font, Text}} | Os], Out) ->
- precompile_objects(Os, [O#image_object{ intervals = text_horizontal_ls(P0, Font, Text) } | Out]);
-
-precompile_objects([O|Os], Out) ->
- precompile_objects(Os, [O|Out]).
+ Ls = lists:foldl(fun ({Ep0,Ep1},M) ->
+ linespans_to_map(line_to_linespans(Ep0,Ep1,1),M)
+ end, #{}, Es),
+ [O#image_object{type=line, intervals=Ls}|precompile_objects(Os)];
+precompile_objects([#image_object{type=text_horizontal,
+ points=[P0], internals={Font,Text}}=O|Os]) ->
+ [O#image_object{intervals=text_horizontal_ls(P0,Font,Text)}|precompile_objects(Os)];
+precompile_objects([O|Os]) ->
+ [O|precompile_objects(Os)].
% triangle
@@ -353,7 +352,8 @@ triangle_ls(P1,P2,P3) ->
% At an end point, a new line to the point already being drawn
% repeat same procedure as above
[Sp1, Sp2, Sp3] = tri_pt_ysort([P1,P2,P3]),
- triangle_ls_lp(tri_ls_ysort(line_ls(Sp1,Sp2)), Sp2, tri_ls_ysort(line_ls(Sp1,Sp3)), Sp3, []).
+ triangle_ls_lp(tri_ls_ysort(line_to_linespans(Sp1,Sp2,1)), Sp2,
+ tri_ls_ysort(line_to_linespans(Sp1,Sp3,1)), Sp3, []).
% There will be Y mismatches between the two lists since bresenham is not perfect.
% I can be remedied with checking intervals this could however be costly and
@@ -362,7 +362,7 @@ triangle_ls(P1,P2,P3) ->
triangle_ls_lp([],_,[],_,Out) -> Out;
triangle_ls_lp(LSs1, P1, [], P2, Out) ->
- SLSs = tri_ls_ysort(line_ls(P2,P1)),
+ SLSs = tri_ls_ysort(line_to_linespans(P2,P1,1)),
N2 = length(SLSs),
N1 = length(LSs1),
if
@@ -376,7 +376,7 @@ triangle_ls_lp(LSs1, P1, [], P2, Out) ->
triangle_ls_lp(LSs1, SLSs, Out)
end;
triangle_ls_lp([], P1, LSs2, P2, Out) ->
- SLSs = tri_ls_ysort(line_ls(P1,P2)),
+ SLSs = tri_ls_ysort(line_to_linespans(P1,P2,1)),
N1 = length(SLSs),
N2 = length(LSs2),
if
@@ -390,21 +390,21 @@ triangle_ls_lp([], P1, LSs2, P2, Out) ->
triangle_ls_lp(SLSs, LSs2, Out)
end;
triangle_ls_lp([LS1|LSs1],P1,[LS2|LSs2],P2, Out) ->
- {Y, Xl1, Xr1} = LS1,
- {_, Xl2, Xr2} = LS2,
+ {Y, Xl1, Xr1,_Ca1} = LS1,
+ {_, Xl2, Xr2,_Ca2} = LS2,
Xr = lists:max([Xl1,Xr1,Xl2,Xr2]),
Xl = lists:min([Xl1,Xr1,Xl2,Xr2]),
- triangle_ls_lp(LSs1,P1, LSs2, P2, [{Y,Xl,Xr}|Out]).
+ triangle_ls_lp(LSs1,P1,LSs2,P2,[{Y,Xl,Xr}|Out]).
triangle_ls_lp([],[],Out) -> Out;
triangle_ls_lp([],_,Out) -> Out;
triangle_ls_lp(_,[],Out) -> Out;
triangle_ls_lp([LS1|LSs1], [LS2|LSs2], Out) ->
- {Y, Xl1, Xr1} = LS1,
- {_, Xl2, Xr2} = LS2,
+ {Y, Xl1, Xr1, _Ca1} = LS1,
+ {_, Xl2, Xr2, _Ca2} = LS2,
Xr = lists:max([Xl1,Xr1,Xl2,Xr2]),
Xl = lists:min([Xl1,Xr1,Xl2,Xr2]),
- triangle_ls_lp(LSs1, LSs2, [{Y,Xl,Xr}|Out]).
+ triangle_ls_lp(LSs1,LSs2,[{Y,Xl,Xr}|Out]).
tri_pt_ysort(Pts) ->
% {X,Y}
@@ -414,9 +414,9 @@ tri_pt_ysort(Pts) ->
end, Pts).
tri_ls_ysort(LSs) ->
- % {Y, Xl, Xr}
+ % {Y, Xl, Xr, Ca}
lists:sort(
- fun ({Y1,_,_},{Y2,_,_}) ->
+ fun ({Y1,_,_,_},{Y2,_,_,_}) ->
if Y1 > Y2 -> false; true -> true end
end, LSs).
@@ -503,69 +503,74 @@ point_inside_triangle(P, P1, P2, P3) ->
points_same_side(P, P2, P1, P3) and
points_same_side(P, P3, P1, P2).
-%% [{Y, Xl, Xr}]
-ls_list2dict(List) -> ls_list2dict(List, dict:new()).
-ls_list2dict([], D) -> D;
-ls_list2dict([{Y, Xl, Xr}|Ls], D) ->
- case dict:is_key(Y, D) of
- false -> ls_list2dict(Ls, dict:store(Y, [{Xl, Xr}], D));
- true -> ls_list2dict(Ls, dict:append(Y, {Xl, Xr}, D))
- end.
+%% [{Y, Xl, Xr}] -> #{Y := [{Xl,Xr}]}
+%% Reorganize linspans to a map with Y as key.
+
+linespans_to_map(Ls) ->
+ linespans_to_map(Ls,#{}).
+linespans_to_map([{Y,Xl,Xr,C}|Ls], M) ->
+ case M of
+ #{Y := Spans} -> linespans_to_map(Ls, M#{Y := [{Xl,Xr,C}|Spans]});
+ _ -> linespans_to_map(Ls, M#{Y => [{Xl,Xr,C}]})
+ end;
+linespans_to_map([], M) ->
+ M.
-%% line_ls
+
+%% line_to_linespans
+%% Anti-aliased thick line
+%% Do it CPS style
%% In:
%% P1 :: point()
%% P2 :: point()
%% Out:
-%% {{Ymin,Ymax}, LSD :: line_step_data()}
-%% Purpose:
-%% Instead of points -> intervals
-
-
-line_ls({Xi0, Yi0},{Xi1,Yi1}) ->
- % swap X with Y if line is steep
- Steep = abs(Yi1 - Yi0) > abs(Xi1 - Xi0),
-
- {Xs0, Ys0, Xs1, Ys1} = case Steep of
- true -> {Yi0,Xi0,Yi1,Xi1};
- false -> {Xi0,Yi0,Xi1,Yi1}
- end,
-
- {X0,Y0,X1,Y1} = case Xs0 > Xs1 of
- true -> {Xs1,Ys1,Xs0,Ys0};
- false -> {Xs0,Ys0,Xs1,Ys1}
- end,
-
- DX = X1 - X0,
- DY = abs(Y1 - Y0),
-
- Error = -DX/2,
-
- Ystep = case Y0 < Y1 of
- true -> 1;
- false -> -1
- end,
- line_ls_step(X0, X1,Y0, DX, DY, Ystep, Error, X0, Steep, []).
-
-%% line_ls_step_(not)_steep
-%% In:
-%% Out:
-%% [{Yi, Xl,Xr}]
-%% Purpose:
-%% Produce an line_interval for each Yi (Y index)
-
-line_ls_step(X, X1, Y, Dx, Dy, Ys, E, X0, false = Steep, LSs) when X < X1, E >= 0 ->
- line_ls_step(X+1,X1,Y+Ys,Dx,Dy,Ys, E - Dx + Dy, X+1, Steep, [{Y,X0,X}|LSs]);
-line_ls_step(X, X1, Y, Dx, Dy, Ys, E, X0, false = Steep, LSs) when X < X1 ->
- line_ls_step(X+1,X1,Y,Dx,Dy,Ys, E + Dy, X0, Steep, LSs);
-line_ls_step(X, _X1, Y, _Dx, _Dy, _Ys, _E, X0, false, LSs) ->
- [{Y,X0,X}|LSs];
-line_ls_step(X, X1, Y, Dx, Dy, Ys, E, _X0, true = Steep, LSs) when X =< X1, E >= 0 ->
- line_ls_step(X+1,X1,Y+Ys,Dx,Dy,Ys, E - Dx + Dy, X, Steep, [{X,Y,Y}|LSs]);
-line_ls_step(X, X1, Y, Dx, Dy, Ys, E, X0, true = Steep, LSs) when X =< X1 ->
- line_ls_step(X+1,X1,Y,Dx,Dy,Ys,E + Dy, X0, Steep, [{X,Y,Y}|LSs]);
-line_ls_step(_X,_,_Y,_Dx,_Dy,_Ys,_E,_X0,_,LSs) ->
- LSs.
+%% [{Y,Xl,Xr}]
+%%
+line_to_linespans({X0,Y0},{X1,Y1},Wd) ->
+ Dx = abs(X1-X0),
+ Dy = abs(Y1-Y0),
+ Sx = if X0 < X1 -> 1; true -> -1 end,
+ Sy = if Y0 < Y1 -> 1; true -> -1 end,
+ E0 = Dx - Dy,
+ Ed = if Dx + Dy =:= 0 -> 1; true -> math:sqrt(Dx*Dx + Dy*Dy) end,
+ line_to_ls(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E0,Ed,(Wd+1)/2,[]).
+
+line_to_ls(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls0) ->
+ C = max(0, 255*(abs(E - Dx+Dy)/Ed - Wd + 1)),
+ Ls1 = [{Y0,X0,X0,C}|Ls0],
+ line_to_ls_sx(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls1,E).
+
+line_to_ls_sx(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls,E2) when 2*E2 > -Dx ->
+ line_to_ls_sx_do(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls,E2+Dy,Y0);
+line_to_ls_sx(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls,E2) ->
+ line_to_ls_sy(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls,E2,X0).
+
+line_to_ls_sx_do(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls0,E2,Y) when E2 < Ed*Wd andalso
+ (Y1 =/= Y orelse Dx > Dy) ->
+ Y2 = Y + Sy,
+ C = max(0,255*(abs(E2)/Ed-Wd+1)),
+ Ls = [{Y2,X0,X0,C}|Ls0],
+ line_to_ls_sx_do(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls,E2+Dx,Y2);
+line_to_ls_sx_do(X0,_Y0,X1,_Y1,_Dx,_Dy,_Sx,_Sy,_E,_Ed,_Wd,Ls,_E2,_Y) when X0 =:= X1 ->
+ Ls;
+line_to_ls_sx_do(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls,_E2,_Y) ->
+ line_to_ls_sy(X0+Sx,Y0,X1,Y1,Dx,Dy,Sx,Sy,E-Dy,Ed,Wd,Ls,E,X0).
+
+line_to_ls_sy(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls0,E2,X) when 2*E2 =< Dy ->
+ line_to_ls_sy_do(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls0,Dx-E2,X);
+line_to_ls_sy(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls0,_E2,_X) ->
+ line_to_ls(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls0).
+
+line_to_ls_sy_do(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls0,E2,X) when E2 < Ed*Wd andalso
+ (X1 =/= X orelse Dx < Dy) ->
+ X2 = X + Sx,
+ C = max(0,255*(abs(E2)/Ed-Wd+1)),
+ Ls = [{Y0,X2,X2,C}|Ls0],
+ line_to_ls_sy_do(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls,E2+Dy,X2);
+line_to_ls_sy_do(_X0,Y0,_X1,Y1,_Dx,_Dy,_Sx,_Sy,_E,_Ed,_Wd,Ls,_E2,_X) when Y0 =:= Y1 ->
+ Ls;
+line_to_ls_sy_do(X0,Y0,X1,Y1,Dx,Dy,Sx,Sy,E,Ed,Wd,Ls0,_E2,_X) ->
+ line_to_ls(X0,Y0+Sy,X1,Y1,Dx,Dy,Sx,Sy,E+Dx,Ed,Wd,Ls0).
% Text
diff --git a/lib/percept/test/egd_SUITE.erl b/lib/percept/test/egd_SUITE.erl
index 3562ceae88..401695dddd 100644
--- a/lib/percept/test/egd_SUITE.erl
+++ b/lib/percept/test/egd_SUITE.erl
@@ -32,6 +32,7 @@
image_primitives/1,
image_colors/1,
image_font/1,
+ image_fans/1,
image_png_compliant/1]).
suite() ->
@@ -41,6 +42,7 @@ suite() ->
all() ->
[image_create_and_destroy, image_shape,
image_primitives, image_colors, image_font,
+ image_fans,
image_png_compliant].
@@ -71,6 +73,7 @@ image_create_and_destroy(Config) when is_list(Config) ->
%% Image color test.
image_colors(Config) when is_list(Config) ->
{W,H} = get_size(proplists:get_value(max_size, Config)),
+ Dir = proplists:get_value(priv_dir, Config),
Image = egd:create(W, H),
put(image_size, {W,H}),
@@ -96,7 +99,15 @@ image_colors(Config) when is_list(Config) ->
ok = egd:line(Image, get_point(), get_point(), Color)
end, HtmlDefaultNames),
- <<_/binary>> = egd:render(Image),
+ Png1 = <<_/binary>> = egd:render(Image,png,[{render_engine, alpha}]),
+ File1 = filename:join(Dir,"image_colors_alpha.png"),
+ ok = egd:save(Png1,File1),
+ ct:log("<p>Image alpha:</p><img src=\"~s\" />~n", [File1]),
+ Png2 = <<_/binary>> = egd:render(Image,png,[{render_engine, opaque}]),
+ File2 = filename:join(Dir,"image_colors_opaque.png"),
+ ok = egd:save(Png2,File2),
+ ct:log("<p>Image opaque:</p><img src=\"~s\" />~n", [File2]),
+
ok = egd:destroy(Image),
erase(image_size),
ok.
@@ -104,6 +115,7 @@ image_colors(Config) when is_list(Config) ->
%% Image shape API test.
image_shape(Config) when is_list(Config) ->
{W,H} = get_size(proplists:get_value(max_size, Config)),
+ Dir = proplists:get_value(priv_dir, Config),
put(image_size, {W,H}),
Im = egd:create(W, H),
@@ -125,15 +137,21 @@ image_shape(Config) when is_list(Config) ->
ok = bitmap_point_has_color(Bitmap, {W,H}, Pt2, Fgc),
ok = bitmap_point_has_color(Bitmap, {W,H}, Pt1, Fgc),
- <<_/binary>> = egd:render(Im, raw_bitmap, [{render_engine, alpha}]),
+ Bin = <<_/binary>> = egd:render(Im, raw_bitmap, [{render_engine, alpha}]),
+ Png = egd_png:binary(W,H,Bin),
+ File = filename:join(Dir,"image_shape.png"),
+ ok = egd:save(Png,File),
+ ct:log("<p>Image:</p><img src=\"~s\" />~n", [File]),
ok = egd:destroy(Im),
+
erase(image_size),
ok.
%% Image shape API test.
image_primitives(Config) when is_list(Config) ->
{W,H} = get_size(proplists:get_value(max_size, Config)),
+ Dir = proplists:get_value(priv_dir, Config),
put(image_size, {W,H}),
Im0 = egd_primitives:create(W, H),
@@ -157,7 +175,11 @@ image_primitives(Config) when is_list(Config) ->
ok = bitmap_point_has_color(Bitmap, {W,H}, Pt2, Fgc),
ok = bitmap_point_has_color(Bitmap, {W,H}, Pt1, Fgc),
- <<_/binary>> = egd_render:binary(Im2, alpha),
+ Bin = <<_/binary>> = egd_render:binary(Im2, alpha),
+ Png = egd_png:binary(W,H,Bin),
+ File = filename:join(Dir,"image_primitives.png"),
+ ok = egd:save(Png,File),
+ ct:log("<p>Image:</p><img src=\"~s\" />~n", [File]),
erase(image_size),
ok.
@@ -165,6 +187,7 @@ image_primitives(Config) when is_list(Config) ->
%% Image font test.
image_font(Config) when is_list(Config) ->
{W,H} = get_size(proplists:get_value(max_size, Config)),
+ Dir = proplists:get_value(priv_dir, Config),
put(image_size, {W,H}),
Im = egd:create(W, H),
Fgc = egd:color({0,130,0}),
@@ -185,25 +208,46 @@ image_font(Config) when is_list(Config) ->
GlyphStr4 = "{|}~", % Codes 123 -> 126
ok = egd:text(Im, get_point(), Font, GlyphStr1, Fgc),
- <<_/binary>> = egd:render(Im, png),
+ Png1 = <<_/binary>> = egd:render(Im, png),
+ File1 = filename:join(Dir,"text1.png"),
+ ok = egd:save(Png1,File1),
+ ct:log("<p>Image:</p><img src=\"~s\" />~n", [File1]),
ok = egd:text(Im, get_point(), Font, NumericStr, Fgc),
- <<_/binary>> = egd:render(Im, png),
+ Png2 = <<_/binary>> = egd:render(Im, png),
+ File2 = filename:join(Dir,"text2.png"),
+ ok = egd:save(Png2,File2),
+ ct:log("<p>Image:</p><img src=\"~s\" />~n", [File2]),
ok = egd:text(Im, get_point(), Font, GlyphStr2, Fgc),
- <<_/binary>> = egd:render(Im, png),
+ Png3 = <<_/binary>> = egd:render(Im, png),
+ File3 = filename:join(Dir,"text3.png"),
+ ok = egd:save(Png3,File3),
+ ct:log("<p>Image:</p><img src=\"~s\" />~n", [File3]),
ok = egd:text(Im, get_point(), Font, AlphaBigStr, Fgc),
- <<_/binary>> = egd:render(Im, png),
+ Png4 = <<_/binary>> = egd:render(Im, png),
+ File4 = filename:join(Dir,"text4.png"),
+ ok = egd:save(Png4,File4),
+ ct:log("<p>Image:</p><img src=\"~s\" />~n", [File4]),
ok = egd:text(Im, get_point(), Font, GlyphStr3, Fgc),
- <<_/binary>> = egd:render(Im, png),
+ Png5 = <<_/binary>> = egd:render(Im, png),
+ File5 = filename:join(Dir,"text5.png"),
+ ok = egd:save(Png5,File5),
+ ct:log("<p>Image:</p><img src=\"~s\" />~n", [File5]),
ok = egd:text(Im, get_point(), Font, AlphaSmStr, Fgc),
- <<_/binary>> = egd:render(Im, png),
+ Png6 = <<_/binary>> = egd:render(Im, png),
+ File6 = filename:join(Dir,"text6.png"),
+ ok = egd:save(Png6,File6),
+ ct:log("<p>Image:</p><img src=\"~s\" />~n", [File6]),
ok = egd:text(Im, get_point(), Font, GlyphStr4, Fgc),
- <<_/binary>> = egd:render(Im, png),
+ Png7 = <<_/binary>> = egd:render(Im, png),
+ File7 = filename:join(Dir,"text7.png"),
+ ok = egd:save(Png7,File7),
+ ct:log("<p>Image:</p><img src=\"~s\" />~n", [File7]),
ok = egd:destroy(Im),
erase(image_size),
@@ -224,6 +268,65 @@ image_png_compliant(Config) when is_list(Config) ->
erase(image_size),
ok.
+image_fans(Config) when is_list(Config) ->
+ W = 1024,
+ H = 800,
+ Dir = proplists:get_value(priv_dir, Config),
+
+ Fun = fun({F,Args},Im) ->
+ erlang:apply(egd_primitives,F,[Im|Args])
+ end,
+
+ %% fan1
+ Ops1 = gen_vertical_fan(1,{0,400},egd:color(red),1024,800,-15),
+ Ops2 = gen_horizontal_fan(1,{512,800},egd:color(green),1024,0,-15),
+
+ Im0 = egd_primitives:create(W,H),
+ Im1 = lists:foldl(Fun, Im0, Ops1 ++ Ops2),
+ Bin1 = egd_render:binary(Im1, opaque),
+ Png1 = egd_png:binary(W,H,Bin1),
+
+ File1 = filename:join(Dir,"fan1_opaque.png"),
+ ok = egd:save(Png1,File1),
+ ct:log("<p>Image opaque width 1:</p><img src=\"~s\" />~n", [File1]),
+
+ Bin2 = egd_render:binary(Im1, alpha),
+ Png2 = egd_png:binary(W,H,Bin2),
+
+ File2 = filename:join(Dir,"fan1_alpha.png"),
+ ok = egd:save(Png2,File2),
+ ct:log("<p>Image alpha width 1:</p><img src=\"~s\" />~n", [File2]),
+
+
+ %% fan2
+ Ops3 = gen_vertical_fan(7,{0,400},egd:color(red),1024,800,-15),
+ Ops4 = gen_horizontal_fan(7,{512,800},egd:color(green),1024,0,-15),
+
+ Im2 = lists:foldl(Fun, Im0, Ops3 ++ Ops4),
+ Bin3 = egd_render:binary(Im2, opaque),
+ Png3 = egd_png:binary(W,H,Bin3),
+
+ File3 = filename:join(Dir,"fan2_opaque.png"),
+ ok = egd:save(Png3,File3),
+ ct:log("<p>Image opaque width 7:</p><img src=\"~s\" />~n", [File3]),
+
+ Bin4 = egd_render:binary(Im2, alpha),
+ Png4 = egd_png:binary(W,H,Bin4),
+
+ File4 = filename:join(Dir,"fan2_alpha.png"),
+ ok = egd:save(Png4,File4),
+ ct:log("<p>Image alpha width 7:</p><img src=\"~s\" />~n", [File4]),
+ ok.
+
+gen_vertical_fan(Wd,Pt,C,X,Y,Step) when Y > 0 ->
+ [{line,[Pt,{X,Y},Wd,C]}|gen_vertical_fan(Wd,Pt,C,X,Y + Step,Step)];
+gen_vertical_fan(_,_,_,_,_,_) -> [].
+
+gen_horizontal_fan(Wd,Pt,C,X,Y,Step) when X > 0 ->
+ [{line,[Pt,{X,Y},Wd,C]}|gen_horizontal_fan(Wd,Pt,C,X + Step,Y,Step)];
+gen_horizontal_fan(_,_,_,_,_,_) -> [].
+
+
%%----------------------------------------------------------------------
%% Auxiliary tests
%%----------------------------------------------------------------------
@@ -239,33 +342,6 @@ bitmap_point_has_color(Bitmap, {W,_}, {X,Y}, C) ->
{error, {Other,{CR,CG,CB}}}
end.
-%% jfif header by specification
-%% 2 bytes, length
-%% 5 bytes, identifier ="JFIF\0"
-%% 2 bytes, version, (major, minor)
-%% 1 byte , units
-%% However, JFIF seems to start at 6 (7 with 1-index)?
-
-binary_is_jfif_compliant(JpegBin) ->
- {Bin, _} = split_binary(JpegBin, 11),
- List = binary_to_list(Bin),
- case lists:sublist(List, 7, 4) of
- "JFIF" -> true;
- Other ->
- io:format("img -> ~p~n", [Other]),
- false
- end.
-
-binary_is_gif_compliant(GifBin) ->
- {Bin, _} = split_binary(GifBin, 10),
- List = binary_to_list(Bin),
- case lists:sublist(List, 1,5) of
- "GIF87" -> true;
- Other ->
- io:format("img -> ~p~n", [Other]),
- false
- end.
-
binary_is_png_compliant(PngBin) ->
{Bin, _} = split_binary(PngBin, 10),
List = binary_to_list(Bin),
diff --git a/lib/public_key/test/pbe_SUITE.erl b/lib/public_key/test/pbe_SUITE.erl
index 4b7ebf4309..004eaefc27 100644
--- a/lib/public_key/test/pbe_SUITE.erl
+++ b/lib/public_key/test/pbe_SUITE.erl
@@ -30,7 +30,8 @@
%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
-suite() -> [{ct_hooks,[ts_install_cth]}].
+suite() ->
+ [].
all() ->
[
@@ -199,7 +200,7 @@ pbdkdf2(Config) when is_list(Config) ->
old_enc() ->
[{doc,"Tests encode/decode RSA key encrypted with different ciphers using old PEM encryption scheme"}].
old_enc(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
%% key generated with ssh-keygen -N hello_aes -f old_aes_128_cbc_enc_key.pem
{ok, PemAesCbc} = file:read_file(filename:join(Datadir, "old_aes_128_cbc_enc_key.pem")),
@@ -226,7 +227,7 @@ check_key_info(#'PrivateKeyInfo'{privateKeyAlgorithm =
#'RSAPrivateKey'{} = public_key:der_decode('RSAPrivateKey', iolist_to_binary(Key)).
decode_encode_key_file(File, Password, Cipher, Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
{ok, PemKey} = file:read_file(filename:join(Datadir, File)),
PemEntry = public_key:pem_decode(PemKey),
diff --git a/lib/public_key/test/pkits_SUITE.erl b/lib/public_key/test/pkits_SUITE.erl
index 17be99b52d..487b3dbe3f 100644
--- a/lib/public_key/test/pkits_SUITE.erl
+++ b/lib/public_key/test/pkits_SUITE.erl
@@ -53,7 +53,7 @@
%%--------------------------------------------------------------------
suite() ->
- [{ct_hooks,[ts_install_cth]}].
+ [].
all() ->
[{group, signature_verification},
diff --git a/lib/public_key/test/public_key_SUITE.erl b/lib/public_key/test/public_key_SUITE.erl
index 51050c4480..9c39c36be4 100644
--- a/lib/public_key/test/public_key_SUITE.erl
+++ b/lib/public_key/test/public_key_SUITE.erl
@@ -34,7 +34,8 @@
%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
-suite() -> [{ct_hooks,[ts_install_cth]}].
+suite() ->
+ [].
all() ->
[app, appup,
@@ -108,7 +109,7 @@ appup(Config) when is_list(Config) ->
dsa_pem() ->
[{doc, "DSA PEM-file decode/encode"}].
dsa_pem(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
[{'DSAPrivateKey', DerDSAKey, not_encrypted} = Entry0 ] =
erl_make_certs:pem_to_der(filename:join(Datadir, "dsa.pem")),
@@ -131,7 +132,7 @@ dsa_pem(Config) when is_list(Config) ->
rsa_pem() ->
[{doc, "RSA PEM-file decode/encode"}].
rsa_pem(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
[{'RSAPrivateKey', DerRSAKey, not_encrypted} = Entry0 ] =
erl_make_certs:pem_to_der(filename:join(Datadir, "client_key.pem")),
@@ -166,7 +167,7 @@ rsa_pem(Config) when is_list(Config) ->
ec_pem() ->
[{doc, "EC key PEM-file decode/encode"}].
ec_pem(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
{ok, ECPubPem} = file:read_file(filename:join(Datadir, "ec_pubkey.pem")),
[{'SubjectPublicKeyInfo', _, _} = PubEntry0] =
public_key:pem_decode(ECPubPem),
@@ -192,7 +193,7 @@ ec_pem(Config) when is_list(Config) ->
encrypted_pem() ->
[{doc, "Encrypted PEM-file decode/encode"}].
encrypted_pem(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
[{'RSAPrivateKey', DerRSAKey, not_encrypted}] =
erl_make_certs:pem_to_der(filename:join(Datadir, "client_key.pem")),
@@ -225,7 +226,7 @@ encrypted_pem(Config) when is_list(Config) ->
dh_pem() ->
[{doc, "DH parametrs PEM-file decode/encode"}].
dh_pem(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
[{'DHParameter', _DerDH, not_encrypted} = Entry] =
erl_make_certs:pem_to_der(filename:join(Datadir, "dh.pem")),
asn1_encode_decode(Entry).
@@ -235,7 +236,7 @@ dh_pem(Config) when is_list(Config) ->
pkcs10_pem() ->
[{doc, "PKCS-10 PEM-file decode/encode"}].
pkcs10_pem(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
[{'CertificationRequest', _DerPKCS10, not_encrypted} = Entry] =
erl_make_certs:pem_to_der(filename:join(Datadir, "req.pem")),
asn1_encode_decode(Entry).
@@ -243,7 +244,7 @@ pkcs10_pem(Config) when is_list(Config) ->
pkcs7_pem() ->
[{doc, "PKCS-7 PEM-file decode/encode"}].
pkcs7_pem(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
[{'ContentInfo', _, not_encrypted} = Entry0] =
erl_make_certs:pem_to_der(filename:join(Datadir, "pkcs7_cert.pem")),
[{'ContentInfo', _, not_encrypted} = Entry1] =
@@ -255,7 +256,7 @@ pkcs7_pem(Config) when is_list(Config) ->
cert_pem() ->
[{doc, "Certificate PEM-file decode/encode"}].
cert_pem(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
[{'Certificate', _, not_encrypted} = Entry0] =
erl_make_certs:pem_to_der(filename:join(Datadir, "client_cert.pem")),
@@ -273,7 +274,7 @@ cert_pem(Config) when is_list(Config) ->
ssh_rsa_public_key() ->
[{doc, "ssh rsa public key decode/encode"}].
ssh_rsa_public_key(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
{ok, RSARawSsh2} = file:read_file(filename:join(Datadir, "ssh2_rsa_pub")),
[{PubKey, Attributes1}] = public_key:ssh_decode(RSARawSsh2, public_key),
@@ -299,7 +300,7 @@ ssh_rsa_public_key(Config) when is_list(Config) ->
ssh_dsa_public_key() ->
[{doc, "ssh dsa public key decode/encode"}].
ssh_dsa_public_key(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
{ok, DSARawSsh2} = file:read_file(filename:join(Datadir, "ssh2_dsa_pub")),
[{PubKey, Attributes1}] = public_key:ssh_decode(DSARawSsh2, public_key),
@@ -325,7 +326,7 @@ ssh_dsa_public_key(Config) when is_list(Config) ->
ssh_ecdsa_public_key() ->
[{doc, "ssh ecdsa public key decode/encode"}].
ssh_ecdsa_public_key(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
{ok, ECDSARawSsh2} = file:read_file(filename:join(Datadir, "ssh2_ecdsa_pub")),
[{PubKey, Attributes1}] = public_key:ssh_decode(ECDSARawSsh2, public_key),
@@ -350,7 +351,7 @@ ssh_ecdsa_public_key(Config) when is_list(Config) ->
ssh_rfc4716_rsa_comment() ->
[{doc, "Test comment header and rsa key"}].
ssh_rfc4716_rsa_comment(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
{ok, RSARawSsh2} = file:read_file(filename:join(Datadir, "ssh2_rsa_comment_pub")),
[{#'RSAPublicKey'{} = PubKey, Attributes}] =
@@ -366,7 +367,7 @@ ssh_rfc4716_rsa_comment(Config) when is_list(Config) ->
ssh_rfc4716_dsa_comment() ->
[{doc, "Test comment header and dsa key"}].
ssh_rfc4716_dsa_comment(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
{ok, DSARawSsh2} = file:read_file(filename:join(Datadir, "ssh2_dsa_comment_pub")),
[{{_, #'Dss-Parms'{}} = PubKey, Attributes}] =
@@ -386,7 +387,7 @@ ssh_rfc4716_dsa_comment(Config) when is_list(Config) ->
ssh_rfc4716_rsa_subject() ->
[{doc, "Test another header value than comment"}].
ssh_rfc4716_rsa_subject(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
{ok, RSARawSsh2} = file:read_file(filename:join(Datadir, "ssh2_subject_pub")),
[{#'RSAPublicKey'{} = PubKey, Attributes}] =
@@ -406,7 +407,7 @@ ssh_rfc4716_rsa_subject(Config) when is_list(Config) ->
ssh_known_hosts() ->
[{doc, "ssh known hosts file encode/decode"}].
ssh_known_hosts(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
{ok, SshKnownHosts} = file:read_file(filename:join(Datadir, "known_hosts")),
[{#'RSAPublicKey'{}, Attributes1}, {#'RSAPublicKey'{}, Attributes2},
@@ -435,7 +436,7 @@ ssh_known_hosts(Config) when is_list(Config) ->
ssh1_known_hosts() ->
[{doc, "ssh (ver 1) known hosts file encode/decode"}].
ssh1_known_hosts(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
{ok, SshKnownHosts} = file:read_file(filename:join(Datadir, "ssh1_known_hosts")),
[{#'RSAPublicKey'{}, Attributes1}, {#'RSAPublicKey'{}, Attributes2},{#'RSAPublicKey'{}, Attributes3}]
@@ -455,7 +456,7 @@ ssh1_known_hosts(Config) when is_list(Config) ->
ssh_auth_keys() ->
[{doc, "ssh authorized keys file encode/decode"}].
ssh_auth_keys(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
{ok, SshAuthKeys} = file:read_file(filename:join(Datadir, "auth_keys")),
[{#'RSAPublicKey'{}, Attributes1}, {{_, #'Dss-Parms'{}}, Attributes2},
@@ -481,7 +482,7 @@ ssh_auth_keys(Config) when is_list(Config) ->
ssh1_auth_keys() ->
[{doc, "ssh (ver 1) authorized keys file encode/decode"}].
ssh1_auth_keys(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
{ok, SshAuthKeys} = file:read_file(filename:join(Datadir, "ssh1_auth_keys")),
[{#'RSAPublicKey'{}, Attributes1},
@@ -509,7 +510,7 @@ ssh1_auth_keys(Config) when is_list(Config) ->
ssh_openssh_public_key_with_comment() ->
[{doc, "Test that emty lines and lines starting with # are ignored"}].
ssh_openssh_public_key_with_comment(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
{ok, DSARawOpenSsh} = file:read_file(filename:join(Datadir, "openssh_dsa_with_comment_pub")),
[{{_, #'Dss-Parms'{}}, _}] = public_key:ssh_decode(DSARawOpenSsh, openssh_public_key).
@@ -518,7 +519,7 @@ ssh_openssh_public_key_with_comment(Config) when is_list(Config) ->
ssh_openssh_public_key_long_header() ->
[{doc, "Test that long headers are handled"}].
ssh_openssh_public_key_long_header(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
{ok,RSARawOpenSsh} = file:read_file(filename:join(Datadir, "ssh_rsa_long_header_pub")),
[{#'RSAPublicKey'{}, _}] = Decoded = public_key:ssh_decode(RSARawOpenSsh, public_key),
@@ -577,7 +578,7 @@ dsa_sign_verify(Config) when is_list(Config) ->
public_key:pem_entry_decode(CertKey1),
true = public_key:pkix_verify(Cert2, {Y, #'Dss-Parms'{p=P, q=Q, g=G}}),
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
[DsaKey = {'DSAPrivateKey', _, _}] =
erl_make_certs:pem_to_der(filename:join(Datadir, "dsa.pem")),
DSAPrivateKey = public_key:pem_entry_decode(DsaKey),
@@ -606,7 +607,7 @@ dsa_sign_verify(Config) when is_list(Config) ->
pkix() ->
[{doc, "Misc pkix tests not covered elsewhere"}].
pkix(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
Certs0 = erl_make_certs:pem_to_der(filename:join(Datadir, "cacerts.pem")),
Certs1 = erl_make_certs:pem_to_der(filename:join(Datadir, "client_cert.pem")),
TestTransform = fun({'Certificate', CertDer, not_encrypted}) ->
@@ -749,7 +750,7 @@ pkix_iso_rsa_oid() ->
[{doc, "Test workaround for supporting certs that use ISO oids"
" 1.3.14.3.2.29 instead of PKIX/PKCS oid"}].
pkix_iso_rsa_oid(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
{ok, PemCert} = file:read_file(filename:join(Datadir, "rsa_ISO.pem")),
[{_, Cert, _}] = public_key:pem_decode(PemCert),
OTPCert = public_key:pkix_decode_cert(Cert, otp),
@@ -761,7 +762,7 @@ pkix_iso_dsa_oid() ->
[{doc, "Test workaround for supporting certs that use ISO oids"
"1.3.14.3.2.27 instead of PKIX/PKCS oid"}].
pkix_iso_dsa_oid(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
{ok, PemCert} = file:read_file(filename:join(Datadir, "dsa_ISO.pem")),
[{_, Cert, _}] = public_key:pem_decode(PemCert),
OTPCert = public_key:pkix_decode_cert(Cert, otp),
@@ -774,7 +775,7 @@ pkix_crl() ->
[{doc, "test pkix_crl_* functions"}].
pkix_crl(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
{ok, PemCRL} = file:read_file(filename:join(Datadir, "idp_crl.pem")),
[{_, CRL, _}] = public_key:pem_decode(PemCRL),
diff --git a/lib/runtime_tools/c_src/trace_ip_drv.c b/lib/runtime_tools/c_src/trace_ip_drv.c
index c73630f702..195558f958 100644
--- a/lib/runtime_tools/c_src/trace_ip_drv.c
+++ b/lib/runtime_tools/c_src/trace_ip_drv.c
@@ -374,6 +374,7 @@ static void trace_ip_output(ErlDrvData handle, char *buff, ErlDrvSizeT bufflen)
}
return;
}
+ ASSERT(!IS_INVALID_SOCKET(data->fd));
if (data->que[data->questart] != NULL) {
trace_ip_ready_output(handle, sock2event(data->fd));
}
@@ -412,6 +413,7 @@ static void trace_ip_ready_input(ErlDrvData handle, ErlDrvEvent fd)
/*
** Maybe accept, we are a listen port...
*/
+ ASSERT(IS_INVALID_SOCKET(data->fd));
if (!IS_INVALID_SOCKET((client = my_accept(data->listenfd)))) {
data->fd = client;
set_nonblocking(client);
@@ -735,6 +737,7 @@ static void close_client(TraceIpData *data)
{
my_driver_select(data, data->fd, FLAG_WRITE | FLAG_READ, SELECT_CLOSE);
data->flags |= FLAG_LISTEN_PORT;
+ data->fd = INVALID_SOCKET;
if (!(data->flags & FLAG_FILL_ALWAYS)) {
clean_que(data);
}
diff --git a/lib/runtime_tools/doc/src/dbg.xml b/lib/runtime_tools/doc/src/dbg.xml
index 103b8b52e9..49b11ddc3c 100644
--- a/lib/runtime_tools/doc/src/dbg.xml
+++ b/lib/runtime_tools/doc/src/dbg.xml
@@ -439,6 +439,50 @@ Error: fun containing local erlang function calls ('is_atomm' called in guard)\
global calls (and functions).</p>
</desc>
</func>
+
+
+ <func>
+ <name>tpe(Event, MatchSpec) -> {ok, MatchDesc} | {error, term()}</name>
+ <fsummary>Set pattern for traced event</fsummary>
+ <type>
+ <v>Event = send | 'receive'</v>
+ <v>MatchSpec = integer() | Built-inAlias | [] | match_spec()</v>
+ <v>Built-inAlias = x | c | cx</v>
+ <v>MatchDesc = [MatchInfo]</v>
+ <v>MatchInfo = {saved, integer()} | MatchNum</v>
+ <v>MatchNum = {matched, node(), 1} | {matched, node(), 0, RPCError}</v>
+ </type>
+ <desc>
+ <p>This function associates a match specification with trace event
+ <c>send</c> or <c>'receive'</c>. By default all executed <c>send</c>
+ and <c>'receive'</c> events are traced if enabled for a process.
+ A match specification can be used to filter traced events
+ based on sender, receiver and/or message content.</p>
+ <p>For a description of the <c>match_spec()</c> syntax,
+ please turn to the <em>User's guide</em> part of the online
+ documentation for the runtime system (<em>erts</em>). The
+ chapter <seealso marker="erts:match_spec"><em>Match Specifications in Erlang</em></seealso>
+ explains the general match specification "language".</p>
+ <p>For <c>send</c>, the matching is done on the list <c>[Receiver, Msg]</c>.
+ <c>Receiver</c> is the process or port identity of the receiver and
+ <c>Msg</c> is the message term. The pid of the sending process can be
+ accessed with the guard function <c>self/0</c>.</p>
+ <p>For <c>'receive'</c>, the matching is done on the list <c>[Node, Sender, Msg]</c>.
+ <c>Node</c> is the node name of the sender. <c>Sender</c> is the
+ process or port identity of the sender, or the atom
+ <c>undefined</c> if the sender is not known (which may
+ be the case for remote senders). <c>Msg</c> is the
+ message term. The pid of the receiving process can be
+ accessed with the guard function <c>self/0</c>.</p>
+ <p>All nodes added with <seealso marker="#n-1"><c>n/1</c></seealso> or
+ <seealso marker="#tracer-3"><c>tracer/3</c></seealso> will
+ be affected by this call.</p>
+ <p>The return value is the same as for
+ <seealso marker="#tp-2"><c>tp/2</c></seealso>. The number of matched
+ events are never larger than 1 as <c>tpe/2</c> does not
+ accept any form of wildcards for argument <c>Event</c>.</p>
+ </desc>
+ </func>
<func>
<name>ctp()</name>
<fsummary>Clear call trace pattern for the specified functions</fsummary>
@@ -563,6 +607,22 @@ Error: fun containing local erlang function calls ('is_atomm' called in guard)\
</desc>
</func>
<func>
+ <name>ctpe(Event) -> {ok, MatchDesc} | {error, term()}</name>
+ <fsummary>Clear trace pattern for the specified event</fsummary>
+ <type>
+ <v>Event = send | 'receive'</v>
+ <v>MatchDesc = [MatchNum]</v>
+ <v>MatchNum = {matched, node(), 1} | {matched, node(), 0, RPCError}</v>
+ </type>
+ <desc>
+ <p>This function clears match specifications for the specified
+ trace event (<c>send</c> or <c>'receive'</c>). It will revert back
+ to the default behavior of tracing all triggered events.</p>
+ <p>The return value follow the same style as for
+ <seealso marker="#ctp-1"><c>ctp/1</c></seealso>.</p>
+ </desc>
+ </func>
+ <func>
<name>ltp() -> ok</name>
<fsummary>List saved and built-in match specifications on the console.</fsummary>
<desc>
diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index 946adcf384..e952a333ff 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.erl
@@ -1514,39 +1514,35 @@ call(FsmPid, Event, Timeout) ->
end.
-handle_connection_msg(Msg, StateName, State0 =
- #data{starter = User,
- connection_state = Connection0,
- event_queue = Qev0}) ->
+handle_connection_msg(Msg, StateName, D0 = #data{starter = User,
+ connection_state = Connection0,
+ event_queue = Qev0}) ->
Renegotiation = renegotiation(StateName),
Role = role(StateName),
- try ssh_connection:handle_msg(Msg, Connection0, Role) of
+ try ssh_connection:handle_msg(Msg, Connection0, Role) of
{{replies, Replies}, Connection} ->
- case StateName of
- {connected,_} ->
- {Repls, State} = send_replies(Replies,
- State0#data{connection_state=Connection}),
- {keep_state, State, Repls};
- _ ->
- {ConnReplies, Replies} =
- lists:splitwith(fun not_connected_filter/1, Replies),
- {Repls, State} = send_replies(Replies,
- State0#data{event_queue = Qev0 ++ ConnReplies}),
- {keep_state, State, Repls}
- end;
+ {Repls, D} =
+ case StateName of
+ {connected,_} ->
+ send_replies(Replies, D0#data{connection_state=Connection});
+ _ ->
+ {ConnReplies, NonConnReplies} = lists:splitwith(fun not_connected_filter/1, Replies),
+ send_replies(NonConnReplies, D0#data{event_queue = Qev0 ++ ConnReplies})
+ end,
+ {keep_state, D, Repls};
{noreply, Connection} ->
- {keep_state, State0#data{connection_state = Connection}};
+ {keep_state, D0#data{connection_state = Connection}};
{disconnect, Reason0, {{replies, Replies}, Connection}} ->
- {Repls,State} = send_replies(Replies, State0#data{connection_state = Connection}),
+ {Repls, D} = send_replies(Replies, D0#data{connection_state = Connection}),
case {Reason0,Role} of
{{_, Reason}, client} when ((StateName =/= {connected,client}) and (not Renegotiation)) ->
User ! {self(), not_connected, Reason};
_ ->
ok
end,
- {stop_and_reply, {shutdown,normal}, Repls, State#data{connection_state = Connection}}
+ {stop_and_reply, {shutdown,normal}, Repls, D#data{connection_state = Connection}}
catch
_:Error ->
@@ -1555,8 +1551,8 @@ handle_connection_msg(Msg, StateName, State0 =
#ssh_msg_disconnect{code = ?SSH_DISCONNECT_BY_APPLICATION,
description = "Internal error"},
Connection0, Role),
- {Repls,State} = send_replies(Replies, State0#data{connection_state = Connection}),
- {stop_and_reply, {shutdown,Error}, Repls, State#data{connection_state = Connection}}
+ {Repls, D} = send_replies(Replies, D0#data{connection_state = Connection}),
+ {stop_and_reply, {shutdown,Error}, Repls, D#data{connection_state = Connection}}
end.
diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl
index dbbb25025c..51732b4a59 100644
--- a/lib/ssl/src/ssl.erl
+++ b/lib/ssl/src/ssl.erl
@@ -400,24 +400,23 @@ negotiated_next_protocol(Socket) ->
end.
%%--------------------------------------------------------------------
+-spec cipher_suites() -> [ssl_cipher:erl_cipher_suite()] | [string()].
+%%--------------------------------------------------------------------
+cipher_suites() ->
+ cipher_suites(erlang).
+%%--------------------------------------------------------------------
-spec cipher_suites(erlang | openssl | all) -> [ssl_cipher:erl_cipher_suite()] |
[string()].
%% Description: Returns all supported cipher suites.
%%--------------------------------------------------------------------
cipher_suites(erlang) ->
- Version = tls_record:highest_protocol_version([]),
- ssl_cipher:filter_suites([ssl_cipher:erl_suite_definition(S)
- || S <- ssl_cipher:suites(Version)]);
+ [ssl_cipher:erl_suite_definition(Suite) || Suite <- available_suites(default)];
+
cipher_suites(openssl) ->
- Version = tls_record:highest_protocol_version([]),
- [ssl_cipher:openssl_suite_name(S)
- || S <- ssl_cipher:filter_suites(ssl_cipher:suites(Version))];
+ [ssl_cipher:openssl_suite_name(Suite) || Suite <- available_suites(default)];
+
cipher_suites(all) ->
- Version = tls_record:highest_protocol_version([]),
- ssl_cipher:filter_suites([ssl_cipher:erl_suite_definition(S)
- || S <-ssl_cipher:all_suites(Version)]).
-cipher_suites() ->
- cipher_suites(erlang).
+ [ssl_cipher:erl_suite_definition(Suite) || Suite <- available_suites(all)].
%%--------------------------------------------------------------------
-spec getopts(#sslsocket{}, [gen_tcp:option_name()]) ->
@@ -584,6 +583,16 @@ format_error(Error) ->
%%%--------------------------------------------------------------
%%% Internal functions
%%%--------------------------------------------------------------------
+
+%% Possible filters out suites not supported by crypto
+available_suites(default) ->
+ Version = tls_record:highest_protocol_version([]),
+ ssl_cipher:filter_suites(ssl_cipher:suites(Version));
+
+available_suites(all) ->
+ Version = tls_record:highest_protocol_version([]),
+ ssl_cipher:filter_suites(ssl_cipher:all_suites(Version)).
+
do_connect(Address, Port,
#config{transport_info = CbInfo, inet_user = UserOpts, ssl = SslOpts,
emulated = EmOpts, inet_ssl = SocketOpts, connection_cb = ConnetionCb},
diff --git a/lib/stdlib/doc/src/digraph.xml b/lib/stdlib/doc/src/digraph.xml
index 16dd789caf..1bb8eef247 100644
--- a/lib/stdlib/doc/src/digraph.xml
+++ b/lib/stdlib/doc/src/digraph.xml
@@ -104,14 +104,12 @@
</datatype>
<datatype>
<name>edge()</name>
- <desc><p><marker id="type-edge"/></p></desc>
</datatype>
<datatype>
<name name="label"/>
</datatype>
<datatype>
<name>vertex()</name>
- <desc><p><marker id="type-vertex"/></p></desc>
</datatype>
</datatypes>
<funcs>
diff --git a/lib/stdlib/doc/src/digraph_utils.xml b/lib/stdlib/doc/src/digraph_utils.xml
index 9bddee546f..e481711c50 100644
--- a/lib/stdlib/doc/src/digraph_utils.xml
+++ b/lib/stdlib/doc/src/digraph_utils.xml
@@ -120,13 +120,6 @@
considering all edges undirected.</p>
</description>
- <datatypes>
- <datatype>
- <name>digraph()</name>
- <desc><p><marker id="type-digraph"/>
- A digraph as returned by <c>digraph:new/0,1</c>.</p></desc>
- </datatype>
- </datatypes>
<funcs>
<func>
<name name="arborescence_root" arity="1"/>
diff --git a/lib/stdlib/doc/src/erl_anno.xml b/lib/stdlib/doc/src/erl_anno.xml
index ddc8b8c765..9f775943c1 100644
--- a/lib/stdlib/doc/src/erl_anno.xml
+++ b/lib/stdlib/doc/src/erl_anno.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2015</year>
- <year>2015</year>
+ <year>2016</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -103,7 +103,7 @@
<datatypes>
<datatype>
<name>anno()</name>
- <desc><p><marker id="type-anno"/>A collection of annotations.</p>
+ <desc><p>A collection of annotations.</p>
</desc>
</datatype>
<datatype>
diff --git a/lib/stdlib/doc/src/erl_parse.xml b/lib/stdlib/doc/src/erl_parse.xml
index 13be488c33..32fce16d68 100644
--- a/lib/stdlib/doc/src/erl_parse.xml
+++ b/lib/stdlib/doc/src/erl_parse.xml
@@ -45,26 +45,22 @@
<datatypes>
<datatype>
<name>abstract_clause()</name>
- <desc><p><marker id="type-abstract_clause"/>
- Abstract form of an Erlang clause.</p>
+ <desc><p>Abstract form of an Erlang clause.</p>
</desc>
</datatype>
<datatype>
<name>abstract_expr()</name>
- <desc><p><marker id="type-abstract_expr"/>
- Abstract form of an Erlang expression.</p>
+ <desc><p>Abstract form of an Erlang expression.</p>
</desc>
</datatype>
<datatype>
<name>abstract_form()</name>
- <desc><p><marker id="type-abstract_form"/>
- Abstract form of an Erlang form.</p>
+ <desc><p>Abstract form of an Erlang form.</p>
</desc>
</datatype>
<datatype>
<name>abstract_type()</name>
- <desc><p><marker id="type-abstract_type"/>
- Abstract form of an Erlang type.</p>
+ <desc><p>Abstract form of an Erlang type.</p>
</desc>
</datatype>
<datatype>
diff --git a/lib/stdlib/doc/src/ets.xml b/lib/stdlib/doc/src/ets.xml
index 2d69c201bc..ad7591e214 100644
--- a/lib/stdlib/doc/src/ets.xml
+++ b/lib/stdlib/doc/src/ets.xml
@@ -123,8 +123,9 @@
<p>Some of the functions uses a <em>match specification</em>,
match_spec. A brief explanation is given in
<seealso marker="#select/2">select/2</seealso>. For a detailed
- description, see the chapter "Match specifications in Erlang" in
- <em>ERTS User's Guide</em>.</p>
+ description, see chapter
+ <seealso marker="erts:match_spec">Match Specifications in Erlang</seealso>
+ in <em>ERTS User's Guide</em>.</p>
</section>
<datatypes>
@@ -134,8 +135,7 @@
<datatype>
<name>continuation()</name>
<desc>
- <p><marker id="type-continuation"/>
- Opaque continuation used by <seealso marker="#select/1">
+ <p>Opaque continuation used by <seealso marker="#select/1">
<c>select/1,3</c></seealso>, <seealso marker="#select_reverse/1">
<c>select_reverse/1,3</c></seealso>, <seealso
marker="#match/1">
diff --git a/lib/stdlib/doc/src/sofs.xml b/lib/stdlib/doc/src/sofs.xml
index cf0855bc85..1e5be367bd 100644
--- a/lib/stdlib/doc/src/sofs.xml
+++ b/lib/stdlib/doc/src/sofs.xml
@@ -399,8 +399,7 @@ fun(S) -> sofs:partition(1, S) end
<datatype>
<!-- Parameterized opaque types are NYI: -->
<name>tuple_of(T)</name>
- <desc><p><marker id="type-tuple_of"/>
- A tuple where the elements are of type <c>T</c>.</p></desc>
+ <desc><p>A tuple where the elements are of type <c>T</c>.</p></desc>
</datatype>
</datatypes>
<funcs>
diff --git a/lib/wx/api_gen/gl_gen.erl b/lib/wx/api_gen/gl_gen.erl
index 0473b7d771..54635bdd2e 100644
--- a/lib/wx/api_gen/gl_gen.erl
+++ b/lib/wx/api_gen/gl_gen.erl
@@ -191,8 +191,9 @@ parse_define([#xmlElement{name=initializer,content=Contents}|_R],Def,_Os) ->
try
case Val0 of
"0x" ++ Val1 ->
- _ = list_to_integer(Val1, 16),
- Def#def{val=Val1, type=hex};
+ Val2 = strip_type_cast(Val1),
+ _ = list_to_integer(Val2, 16),
+ Def#def{val=Val2, type=hex};
_ ->
Val = list_to_integer(Val0),
Def#def{val=Val, type=int}
@@ -214,6 +215,15 @@ extract_def2([#xmlElement{content=Cs}|R]) ->
extract_def2(Cs) ++ extract_def2(R);
extract_def2([]) -> [].
+strip_type_cast(Int) ->
+ lists:reverse(strip_type_cast2(lists:reverse(Int))).
+
+strip_type_cast2("u"++Rest) -> Rest; %% unsigned
+strip_type_cast2("lu"++Rest) -> Rest; %% unsigned long
+strip_type_cast2("llu"++Rest) -> Rest; %% unsigned long long
+strip_type_cast2(Rest) -> Rest.
+
+
strip_comment("/*" ++ Rest) ->
strip_comment_until_end(Rest);
strip_comment("//" ++ _) -> [];
diff --git a/lib/wx/c_src/wxe_helpers.cpp b/lib/wx/c_src/wxe_helpers.cpp
index 4798e605e8..d1f607d2af 100644
--- a/lib/wx/c_src/wxe_helpers.cpp
+++ b/lib/wx/c_src/wxe_helpers.cpp
@@ -48,7 +48,7 @@ void wxeCommand::Delete()
driver_free(buffer);
buffer = NULL;
}
- op = -1;
+ op = -2;
}
/* ****************************************************************************
@@ -84,7 +84,7 @@ wxeCommand * wxeFifo::Get()
pos = m_first++;
m_n--;
m_first %= m_max;
- } while(m_q[pos].op == -1);
+ } while(m_q[pos].op < 0);
return &m_q[pos];
}
@@ -96,7 +96,7 @@ wxeCommand * wxeFifo::Peek(unsigned int *i)
return NULL;
pos = (m_first+*i) % m_max;
(*i)++;
- } while(m_q[pos].op == -1);
+ } while(m_q[pos].op < 0);
return &m_q[pos];
}
@@ -213,7 +213,7 @@ void wxeFifo::Realloc()
// Strip end of queue if ops are already taken care of, avoids reallocs
void wxeFifo::Strip()
{
- while((m_n > 0) && (m_q[(m_first + m_n - 1)%m_max].op == -1)) {
+ while((m_n > 0) && (m_q[(m_first + m_n - 1)%m_max].op < -1)) {
m_n--;
}
}
diff --git a/lib/wx/include/gl.hrl b/lib/wx/include/gl.hrl
index 39cd474fcb..d708515e1b 100644
--- a/lib/wx/include/gl.hrl
+++ b/lib/wx/include/gl.hrl
@@ -1723,7 +1723,7 @@
-define(GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER, 16#8A44).
-define(GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER, 16#8A45).
-define(GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER, 16#8A46).
--define(GL_INVALID_INDEX, 16#FFFFFFFFu).
+-define(GL_INVALID_INDEX, 16#FFFFFFFF).
-define(GL_COPY_READ_BUFFER, 16#8F36).
-define(GL_COPY_WRITE_BUFFER, 16#8F37).
-define(GL_DEPTH_CLAMP, 16#864F).
@@ -1746,7 +1746,7 @@
-define(GL_CONDITION_SATISFIED, 16#911C).
-define(GL_WAIT_FAILED, 16#911D).
-define(GL_SYNC_FLUSH_COMMANDS_BIT, 16#00000001).
--define(GL_TIMEOUT_IGNORED, 16#FFFFFFFFFFFFFFFFull).
+-define(GL_TIMEOUT_IGNORED, 16#FFFFFFFFFFFFFFFF).
-define(GL_SAMPLE_POSITION, 16#8E50).
-define(GL_SAMPLE_MASK, 16#8E51).
-define(GL_SAMPLE_MASK_VALUE, 16#8E52).
diff --git a/lib/wx/test/wx_class_SUITE.erl b/lib/wx/test/wx_class_SUITE.erl
index 6944a78360..0a3c4659bf 100644
--- a/lib/wx/test/wx_class_SUITE.erl
+++ b/lib/wx/test/wx_class_SUITE.erl
@@ -646,8 +646,8 @@ modal(Config) ->
%% need to sleep so we know that the window is stuck in
%% the ShowModal event loop and not in an earlier event loop
%% wx2.8 invokes the event loop from more calls than wx-3
- receive {dialog, M1, 1} -> timer:sleep(1200), ets:insert(test_state, {M1, ready}) end,
- receive {dialog, M2, 2} -> timer:sleep(1200), ets:insert(test_state, {M2, ready}) end,
+ M1 = receive {dialog, W1, 1} -> timer:sleep(1200), ets:insert(test_state, {W1, ready}), W1 end,
+ M2 = receive {dialog, W2, 2} -> timer:sleep(1200), ets:insert(test_state, {W2, ready}), W2 end,
receive done -> ok end,
receive {dialog_done, M2, 2} -> M2 end,